全部函数通过杭电 1142,1162,1198,1213等题目测试。

#include<iostream>
#include<vector>
#include<queue>
#include<stack>
#include<algorithm>
#include<stdio.h>
#include<stdlib.h>
using namespace std; /*
//函数集合声明下,方便查看
void Dijkstra(const denseGraph& dg, int s);
void spfa(const denseGraph& dg, int s);
weightType prim(const denseGraph& dg, int s);
void makeSet(int x);
int findSet(int x);
void unionSet(int x, int y);
weightType kruskal(const denseGraph& dg);
*/ //稀疏图,邻接链表表示
#define N 1000 //表示顶点数最大值
#define NOEDGE 1000000 //表示无边,用于距离类求解中
typedef double weightType; //表示带边权的类型
struct edge{
int v, w;
weightType val;
edge(int v = -, int w = -, weightType val = NOEDGE) :v(v), w(w), val(val){}
};
struct nodeGraph{
int v;
weightType val;
nodeGraph* next;
nodeGraph(int v = -, weightType val = NOEDGE, nodeGraph* next = NULL) :v(v), val(val), next(next){}
};
typedef nodeGraph* link;
struct sparseGraph{
int Vcnt, Ecnt; //顶点数,边数
bool dg; //有向图 ?
vector<link> adj; //邻接链表
sparseGraph(int v, bool dg = false) :adj(v), Vcnt(v), Ecnt(), dg(dg){
adj.assign(v, NULL);
}
void insert(edge e){
int v = e.v, w = e.w;
weightType val = e.val;
adj[v] = new nodeGraph(w, val, adj[v]);
if (!dg) adj[w] = new nodeGraph(v, val, adj[w]);
++Ecnt;
}
void show(){
printf("Vcnt = %d, Ecnt = %d, Directed : %d\n", Vcnt, Ecnt, dg);
link p = NULL;
for (int i = ; i < Vcnt; ++i){
p = adj[i];
printf("%d: ", i);
while (p){
cout << p->v << ',';
cout << p->val;
p = p->next;
if (p) printf(" ");
}
printf("\n");
}
}
}; //用于Dijkstra,prim中的队列优化,可选
struct keyValue{
int key, value;
keyValue(int key, int value) :key(key), value(value){}
};
template<class T>
struct myGreater{
bool operator() (const T& x, const T& y) const{ return x.key > y.key; }
}; //Dijkstra算法
weightType dDijkstra[N]; //存放所有顶点到 s 的最短路径距离
int pDijkstra[N]; //pDijkstra[i],路径存在时,存放节点 i 的前驱,不存在时,-1
void Dijkstra(const sparseGraph &sg, int s)
{
bool visit[N];
for (int i = ; i < sg.Vcnt; ++i){
visit[i] = false;
dDijkstra[i] = NOEDGE;
pDijkstra[i] = -;
}
link p = sg.adj[s];
while (p){
dDijkstra[p->v] = p->val;
pDijkstra[p->v] = s;
p = p->next;
}
visit[s] = true; dDijkstra[s] = ;
for (int i = ; i < sg.Vcnt - ; ++i){
int min = NOEDGE;
int v = ;
/*优先队列代替
priority_queue < keyValue, vector<keyValue>, myGreater<keyValue> > qq;
for (int j = 0; j < sg.Vcnt; ++j)
if (!visit[j]) qq.push(keyValue(dDijkstra[j], j));
keyValue u = qq.top();
v = u.value; min = dDijkstra[v];
*/
for (int j = ; j < sg.Vcnt; ++j){
if (!visit[j] && dDijkstra[j] < min){
v = j; min = dDijkstra[j];
}
}
visit[v] = true;
p = sg.adj[v];
while (p){
if (!visit[p->v] && p->val + min < dDijkstra[p->v]){
dDijkstra[p->v] = p->val + min;
pDijkstra[p->v] = v;
}
p = p->next;
}
}
} //最短路径 SPFA算法
weightType dSpfa[N];
int pSpfa[N];
void spfa(const sparseGraph& sg, int s)
{
bool visit[N];
for (int i = ; i < sg.Vcnt; ++i){
visit[i] = false;
dSpfa[i] = NOEDGE;
pSpfa[i] = -;
}
dSpfa[s] = ;
int u;
link p = NULL;
queue<int> q;
q.push(s);
while (!q.empty()){
u = q.front(); q.pop();
p = sg.adj[u];
while (p){
int v = p->v;
if (dSpfa[u] + p->val < dSpfa[v]){
dSpfa[v] = dSpfa[u] + p->val;
pSpfa[v] = u;
if (!visit[v]) q.push(v);
}
p = p->next;
}
}
}
//最小生成树 prim
weightType dPrim[N]; //存放所有顶点到 s 的最短路径距离
weightType prim(const sparseGraph &sg, int s)
{
weightType sum = ;
bool visit[N];
for (int i = ; i < sg.Vcnt; ++i){
visit[i] = false;
dPrim[i] = NOEDGE;
}
link p = sg.adj[s];
while (p){
dPrim[p->v] = p->val;
p = p->next;
}
visit[s] = true; dPrim[s] = ;
for (int i = ; i < sg.Vcnt - ; ++i){
weightType min = NOEDGE;
int v = ;
for (int j = ; j < sg.Vcnt; ++j){
if (!visit[j] && dPrim[j] < min){
v = j; min = dPrim[j];
}
}
sum += min;
visit[v] = true;
p = sg.adj[v];
while (p){
if (!visit[p->v] && p->val < dPrim[p->v]){
dPrim[p->v] = p->val;
}
p = p->next;
}
}
return sum;
} //并查集实现,点集[0,1,2,3,4,...,n-1]
int parentSet[N];
int rankSet[N];
void makeSet(int x)
{
parentSet[x] = x;
rankSet[x] = ;
}
void linkSet(int x, int y)
{
if (rankSet[x] > rankSet[y])
parentSet[y] = x;
else {
parentSet[x] = y;
if (rankSet[x] == rankSet[y])
++rankSet[y];
}
}
int findSet(int x)
{
vector<int> v;
while (parentSet[x] != x){
v.push_back(x);
x = parentSet[x];
}
for (int i = ; i < v.size(); ++i)
parentSet[v[i]] = x;
return x;
}
void unionSet(int x, int y)
{
linkSet(findSet(x), findSet(y));
} //最小生成树 kruskal
bool kruskalComp(const edge &a, const edge &b){
return a.val < b.val;
}
weightType kruskal(const sparseGraph &sg)
{
weightType sum = ;
vector<edge> ve; //取图的所有边,并排序
edge e;
link p = NULL;
for (int i = ; i < sg.Vcnt; ++i){
p = sg.adj[i];
e.v = i;
while (p){
e.w = p->v;
e.val = p->val;
ve.push_back(e);
p = p->next;
}
}
sort(ve.begin(), ve.end(), kruskalComp);
for (int i = ; i < sg.Vcnt; ++i)
makeSet(i);
for (int i = ; i < ve.size(); ++i){
e = ve[i];
int x = findSet(e.v);
int y = findSet(e.w);
if (x != y){
unionSet(x, y);
sum += e.val;
}
}
return sum;
}
/*测试数据
5 6
1 3 2
1 4 2
3 4 3
1 5 12
4 2 34
5 2 24 7 8
1 3 1
1 4 1
3 7 1
7 4 1
7 5 1
6 7 1
5 2 1
6 2 1
*/
int main()
{
int v, w, val, n, m;
cin >> n >> m;
sparseGraph sg(n,true);
while (m--){
cin >> v >> w >> val;
sg.insert(edge(v-, w-, val));
}
sg.show();
cout << endl;
for (int i = ; i < sg.Vcnt; ++i){
spfa(sg, i);
Dijkstra(sg, i);
for (int i = ; i < sg.Vcnt; ++i)
cout << dSpfa[i] << ' ';
cout << endl;
for (int i = ; i < sg.Vcnt; ++i)
cout << dDijkstra[i] << ' ';
cout << endl; for (int i = ; i < sg.Vcnt; ++i)
cout << pSpfa[i] << ' ';
cout << endl;
for (int i = ; i < sg.Vcnt; ++i)
cout << pDijkstra[i] << ' ';
cout << endl << endl;
}
for (int i = ; i < sg.Vcnt; ++i)
cout << prim(sg, i) << endl;
cout << kruskal(sg) << endl;
}

稀疏图(邻接链表),并查集,最短路径(Dijkstra,spfa),最小生成树(kruskal,prim)的更多相关文章

  1. Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) Problem C (Codeforces 828C) - 链表 - 并查集

    Ivan had string s consisting of small English letters. However, his friend Julia decided to make fun ...

  2. 洛谷P4768 [NOI2018]归程 [可持久化并查集,Dijkstra]

    题目传送门 归程 格式难调,题面就不放了. 分析: 之前同步赛的时候反正就一脸懵逼,然后场场暴力大战,现在呢,还是不会$Kruskal$重构树,于是就拿可持久化并查集做. 但是之前做可持久化并查集的时 ...

  3. [数据结构与算法-15]单源最短路径(Dijkstra+SPFA)

    单源最短路径 问题描述 分别求出从起点到其他所有点的最短路径,这次主要介绍两种算法,Dijkstra和SPFA.若无负权优先Dijkstra算法,存在负权选择SPFA算法. Dijkstra算法 非负 ...

  4. hdu 1272 判断所给的图是不是生成树 (并查集)

    判断所给的图是不是生成树,如果有环就不是,如果没环但连通分量大于1也不是 find函数 用递归写的话 会无限栈溢出 Orz要加上那一串 手动扩栈 Sample Input6 8 5 3 5 2 6 4 ...

  5. [CTSC1999]家园 分层图网络流_并查集

    Code: #include<cstdio> #include<vector> #include<algorithm> #include<queue> ...

  6. 九度OJ 1024 畅通工程 -- 并查集、贪心算法(最小生成树)

    题目地址:http://ac.jobdu.com/problem.php?pid=1024 题目描述:     省政府"畅通工程"的目标是使全省任何两个村庄间都可以实现公路交通(但 ...

  7. fzu 2087并查集的运用求最小生成树的等效边

    //对数组排序后,对于边相同并且边的两端不在一个集合内的一定是等效边或者必加边, //第一数数,第二合并集合 #include<stdio.h> #include<stdlib.h& ...

  8. 判断图连通的三种方法——dfs,bfs,并查集

    Description 如果无向图G每对顶点v和w都有从v到w的路径,那么称无向图G是连通的.现在给定一张无向图,判断它是否是连通的. Input 第一行有2个整数n和m(0 < n,m < ...

  9. PAT Advanced 1013 Battle Over Cities (25) [图的遍历,统计连通分量的个数,DFS,BFS,并查集]

    题目 It is vitally important to have all the cities connected by highways in a war. If a city is occup ...

  10. 并查集(UVA 1106)

    POINT: 把每个元素看成顶点,则一个简单化合物就是一条无向边,若存在环(即k对组合中有k种元素),则危险,不应该装箱,反之,装箱: 用一个并查集维护连通分量集合,每次得到一种化合物(x, y)时检 ...

随机推荐

  1. PHP_CURL请求教程, 内含简单粗暴curl

    //curl访问 //需要url或者data //返回的数组是JSON数据形式 function ppd_curl($url,$data = null){ //\Think\Log::record($ ...

  2. mac10.9 设置vim tab

    vimrc系统文件目录 /usr/share/vim 在vimrc中添加以下代码后,重启vim即可实现按TAB产生4个空格:set ts=4  (注:ts是tabstop的缩写,设TAB宽4个空格)s ...

  3. ubuntu中vim找不到配色方案blackboard

    在ubuntu下启动vim,提示找不到配色方案blackboard(或其他的), 如何挑选自己喜欢的配色方案呢?在/usr/share/vim/vim72/colors中,(这里根据自己的vim版本选 ...

  4. Leetcode算法刷题:第112题 Path Sum

    Path Sum 题目 给予一个二叉树,和一个值su,寻找是否有一个从根节点到叶节点的和为su,有则返回True,没有为False.比如: 5 / \ 4 8 / / \ 11 13 4 / \ \ ...

  5. 1 起步-Pro Git---VCS比较、git基本原理、git配置

    本地版本控制系统 集中化的版本控制系统 诸如 CVS,Subversion 以及 Perforce 等,都有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务 ...

  6. jQuery插件jqplot的详细配置说明和渲染器

    jQuery插件jqplot的详细配置说明和渲染器 (2012-08-23 08:57:42) 转载▼ 标签: jqplot 详细配置 渲染器 it 分类: 技术类 jQuery.jqplot插件的官 ...

  7. 构建混合云:配置Azure site to site VPN连接(2)

    那么接下来的部分,我们开始正式配置S2S VPN: 首先配置本地网络,什么是本地网络呢?如果你在Azure上配置,本地网络意思是你自己的数据中心需要和Azure进行连接的网络段,而不是Azure上的网 ...

  8. ui原则

    http://www.niushe.com/news/show-3683.html 设计师Joshua Porter发表了一篇文章——<Principles of User Interface ...

  9. Excel导入到DataTable

    1.前台代码 <asp:FileUpload ID="fupFiles" runat="server" /> <asp:Button ID=& ...

  10. Inno Setup 系统托盘图标插件 TrayIconCtrl V1.5

    原文 http://restools.hanzify.org/article.asp?id=93 V1.5 修正在某些 Windows 平台上(例如 Windows XP SP3)不能正常运行的问题. ...