图论小结
来源:互联网 发布:dcp打包软件 编辑:程序博客网 时间:2024/06/15 13:30
BellmanFord\dijkstra\堆优化\FloydWarshall\prime\kruskal算法的简单实现
//图的表示const int maxv = 1e5;//struct Edge{ int to, cost; };//vector<Edge> G[maxv];vector<int> G[maxv];int main(){ int v, e; scanf("%d%d", &v, &e); //Edge temp; for(int i = 0; i < e; i++){ int s, t; scanf("%d%d", &s, &t); G[s].push_back(t); G[t].push_back(s); } return 0;}//图的遍历、 二分图染色判定问题const int maxv = 1e5;vector<int> G[maxv];int color[maxv];int V;//顶点染成1或-1 bool dfs(int v, int c){ color[v] = c;//顶点c染成颜色c for(int i = 0; i < G[v].size(); i++){ if(color[G[v][i]] == c) return false;//相邻顶点同色 //如果相邻顶点还没被染色,则染成-c if(color[G[v][i]] == 0 && !dfs(G[v][i], -c)) return false; } //如果所有顶点都染过色了,则返回true; return true;}void slove(){ for(int i = 0; i < V; i++){ if(color[i] == 0){//如果顶点没有被染色,染1; if(!dfs(i, 1)){ printf("No\n"); return; } } } printf("Yes\n");}//单源最短路:BellmanFord算法const int inf = 1e9;const int maxv = 1e5;struct edge{ int from, to, cost; };edge es[maxv];int d[maxv];int pre[maxv];int V, E;//单源最短路:BellmanFord算法void BellmanFord(int s){ for(int i = 0; i < V; i++) d[i] = inf; d[s] = 0; pre[s] = -1; while(true){ bool update = false; for(int i = 0; i < E; i++){ edge e = es[i]; if(d[e.from] != inf && d[e.to] > d[e.from] + e.cost){ d[e.to] = d[e.from] + e.cost; pre[e.to] = e.from; update = true; } } if(!update) break; }}//路径还原 void getPath(int v){ if(pre[v] == -1){ printf("%d ", v); return; } getPath(pre[v]); printf("%d ", v);}//检查是否存在负圈bool findNegativeLoop(){ memset(d, 0, sizeof(d)); for(int i = 0; i < V; i++){ for(int j = 0; j < E; j++){ edge e = es[j]; if(d[e.to] > d[e.from] + e.cost){ d[e.to] = d[e.from] + e.cost; //如果第n次仍更新了,则存在负圈 if(i == V - 1) return false; } } } return true;} int main(){ scanf("%d%d", &V, &E); E *= 2; for(int i = 0; i < E; i+= 2){ scanf("%d%d%d", &es[i].from, &es[i].to, &es[i].cost); es[i+1].from = es[i].to; es[i+1].to = es[i].from; es[i+1].cost = es[i].cost; } BellmanFord(0); cout << d[6] << endl; getPath(6);cout << endl; string str = findNegativeLoop() ? "No negative loop" : "Exist negative loop"; cout << str << endl; return 0;}/*input:7 10 0 1 20 2 51 2 41 3 61 4 102 3 23 5 14 5 34 6 55 6 9output:160 2 3 5 4 6No negative loop*/const int inf = 1e8;const int maxv = 1e3;int cost[maxv][maxv];//初始化inf int d[maxv];bool used[maxv];int pre[maxv];int V, E;//单源最短路:Dijkstra算法 O(V^2)void Dijkstra(int s){ for(int i = 0; i < V; i++){ d[i] = inf; used[i] = false; } d[s] = 0; pre[s] = -1; while(true){ int v = -1; for(int i = 0; i < V; i++){ if(!used[i] && (v == -1 || d[i] < d[v])){ v = i; } } if(v == -1) break; used[v] = true; for(int i = 0; i < V; i++){ if(d[i] > d[v] + cost[v][i]){ d[i] = d[v] + cost[v][i]; pre[i] = v; } } }}//路径还原 void getPath(int v){ if(pre[v] == -1){ printf("%d ", v); return; } getPath(pre[v]); printf("%d ", v);}int main(){ scanf("%d%d", &V, &E); int u, v, val; for(int i = 0; i < V; i++){ for(int j = 0; j < V; j++){ cost[i][j] = inf; } } for(int i = 0; i < E; i++){ scanf("%d%d%d", &u, &v, &val); cost[u][v] = cost[v][u] = val; } Dijkstra(0); cout << d[6] << endl; getPath(6);cout << endl; return 0;}/*input:7 10 0 1 20 2 51 2 41 3 61 4 102 3 23 5 14 5 34 6 55 6 9output:160 2 3 5 4 6*///单源最短路:Dijkstra算法 堆优化O(E*logV)const int inf = 1e8;const int maxv = 1e3;struct edge{int to, cost;}; struct Node{ int dis, v;//最短距离及对应的顶点 friend bool operator < (Node n1, Node n2){ return n1.dis > n2.dis; } };vector<edge> G[maxv];int pre[maxv];int d[maxv];int V, E;//单源最短路:Dijkstra算法 堆优化O(E*logV)void Dijkstra(int s){ fill(d, d + V, inf); d[s] = 0; pre[s] = -1; priority_queue<Node> que; Node temp; temp.dis = 0; temp.v = s; que.push(temp); while(!que.empty()){ Node node = que.top(); que.pop(); int v = node.v; if(d[v] < node.dis) continue; for(int i = 0; i < G[v].size(); i++){ edge e = G[v][i]; if(d[e.to] > d[v] + e.cost){ d[e.to] = d[v] + e.cost; temp.dis = d[e.to]; temp.v = e.to; que.push(temp); pre[e.to] = v; } } }}//路径还原 void getPath(int v){ if(pre[v] == -1){ printf("%d ", v); return; } getPath(pre[v]); printf("%d ", v);}int main(){ scanf("%d%d", &V, &E); int u, v, val; edge temp; for(int i = 0; i < E; i++){ scanf("%d%d%d", &u, &v, &val); temp.cost = val; temp.to = v; G[u].push_back(temp); temp.to = u; G[v].push_back(temp); } Dijkstra(0); cout << d[6] << endl; getPath(6);cout << endl; return 0;}/*input:7 10 0 1 20 2 51 2 41 3 61 4 102 3 23 5 14 5 34 6 55 6 9output:160 2 3 5 4 6*/const int inf = 1e8;const int maxv = 1e3;int d[maxv][maxv];int V, E;//任意两点间最短距离 Floyd-Warshall算法 O(V^3) void FloydWarshall(){ for(int k = 0; k < V; k++){ for(int i = 0; i < V; i++){ for(int j = 0; j < V; j++) d[i][j] = min(d[i][j], d[i][k] + d[k][j]); } }}int main(){ scanf("%d%d", &V, &E); for(int i = 0; i < V; i++){ for(int j = 0; j < V; j++){ if(i == j){ d[i][j] = 0; }else d[i][j] = inf; } } int u, v, val; for(int i = 0; i < E; i++){ scanf("%d%d%d", &u, &v, &val); d[u][v] = d[v][u] = val; } FloydWarshall(); cout << d[0][6] << endl; return 0;}/*input:7 10 0 1 20 2 51 2 41 3 61 4 102 3 23 5 14 5 34 6 55 6 9output:16*///最小生成树、prime算法,同dijkstra算法类似const int inf = 1e8;const int maxv = 1e3;int cost[maxv][maxv];int mincost[maxv]; //从集合x出发的到每个顶点的最小权值bool used[maxv]; //顶点是否包含在集合x中(集合x为MST的子集) int V, E; //最小生成树: prime算法int Prime(){ for(int i = 0; i < V; i++){ mincost[i] = inf; used[i] = false; } mincost[0] = 0; int res = 0; while(true){ int v = -1; for(int i = 0; i < V; i++){ if(!used[i] && (v == -1 || mincost[i] < mincost[v])){ v = i; } } if(v == -1) break; used[v] = true; res += mincost[v]; for(int i = 0; i < V; i++){ mincost[i] = min(mincost[i], cost[v][i]); } } return res;} int main(){ scanf("%d%d", &V, &E); for(int i = 0; i < V; i++){ for(int j = 0; j < V; j++){ cost[i][j] = inf; } } int u, v, val; for(int i = 0; i < E; i++){ scanf("%d%d%d", &u, &v, &val); cost[u][v] = cost[v][u] = val; } cout << "MST: " << Prime() << endl; return 0;}/*input:7 10 0 1 20 2 51 2 41 3 61 4 102 3 23 5 14 5 34 6 55 6 9output:MST: 17*///最小生成树: kruskal算法#include<stdio.h>#include<iostream>#include<string.h>#include<math.h>#include<algorithm>#include<queue>#include<set>#include<iterator>#include<map>#include<stack>using namespace std;const int inf = 1e8;const int maxv = 1e3;struct edge{int u, v, cost; };bool cmp(edge e1, edge e2){ return e1.cost < e2.cost;}edge es[maxv];int root[maxv];int rank[maxv];int V, E; void init(int v){ for(int i = 0; i < V; i++){ root[i] = i; rank[i] = 0; }} int find(int x){ if(root[x] == x) return x; return root[x] = find(root[x]);}bool same(int x, int y){ return find(x) == find(y);}void unit(int x, int y){ x = find(x); y = find(y); if(x == y) return; if(rank[x] < rank[y]){ root[x] = y; }else{ root[y] = x; if(rank[x] == rank[y]) rank[x]++; }}//最小生成树: kruskal算法int Kruskal(){ sort(es, es + E, cmp); init(V);//并查集初始化 int res = 0; for(int i = 0; i < E; i++){ if(!same(es[i].u, es[i].v)){ unit(es[i].u, es[i].v); res += es[i].cost; } } return res; }int main(){ scanf("%d%d", &V, &E); int u, v, val; for(int i = 0; i < E; i++){ scanf("%d%d%d", &es[i].u, &es[i].v, &es[i].cost); } cout << "MST: " << Kruskal() << endl; return 0;}/*input:7 10 0 1 20 2 51 2 41 3 61 4 102 3 23 5 14 5 34 6 55 6 9output:MST: 17*/
阅读全文
0 0
- 图论算法小结
- 图论小结
- 图论算法小结
- 【图论小结】
- 图论小结(6.7)
- 图论小结
- 图论小结
- 初学图论小结
- 图论专题小结:无根树转有根树
- 图论专题小结:最短路算法
- 图论专题小结:拓扑排序
- 图论算法小结:欧拉回路
- 图论小结(最小生成树)
- 贝叶斯决策论小结
- 贝叶斯决策论小结
- 图的连通性小结
- 图的小结
- UML图 小结
- eclipse 编辑窗口不见了(打开左边的java、xml文件,中间不会显示代码)
- Hessian序列化对象之BasicSerializer(五)
- Python 爬虫 工具 列表
- Python——程序入口main函数
- 30最棒的响应式css前端框架
- 图论小结
- 牛客网编程基础1-5
- 53. Maximum Subarray
- 《一个Android工程的从零开始》-8、base(七) Retrofit的封装
- 编译安装tcpdump
- ZeroMQ/jzmq安装使用
- JS教程
- Java 写一个方法判断一个字符串是否对称 "asdfgasdfg"、编写一个程序,将下面的一段文本中的各个单词的字母顺序翻转,
- 博客收藏