【图论】最短路径&&最小生成树问题
2017-08-09 14:51
351 查看
最短路径的算法实现:
1。Dijkstra算法
2。SPFA算法
最小生成树的实现:
3。Prime算法
4。Kruskal算法
1。Dijkstra算法
2。SPFA算法
3。Prime算法
4。Kruskal算法
1。Dijkstra算法
2。SPFA算法
最小生成树的实现:
3。Prime算法
4。Kruskal算法
1。Dijkstra算法
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int INF = 0x3fffffff; //最大顶点数 const int maxn = 1000; //各个顶点到源点的距离 int dis[maxn]; //邻接矩阵 int g[maxn][maxn]; //顶点和边 int n, m; //标记是否已经处理过 bool v[maxn]; void dijkstra(int src) { for(int i = 1; i <= n; i++) { dis[i] = INF; } //源点从1开始 dis[src] = 0; memset(v, 0, sizeof(v)); for(int i = 1; i <= n; i++) { int mark = -1, mindis = INF; for(int j = 1; j <= n; j++) { if(!v[j] && dis[j] < mindis) { mindis = dis[j]; mark = j; } } //题目保证存在最短路径 v[mark] = 1; for(int j = 1; j <= n; j++) { if(!v[j]) { dis[j] = min(dis[j], dis[mark]+g[mark][j]); } } } } int main() { while(scanf("%d%d", &n, &m) != EOF) { for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { g[i][j] = INF; } } int from, to, d; for(int i = 1; i <= m; i++) { scanf("%d%d%d", &from, &to, &d); g[from][to] = d; g[to][from] = d; } dijkstra(5); for(int i = 1; i <= n; i++) { printf("d[%d] = %d\n", i, dis[i]); } } return 0; }
2。SPFA算法
#include <iostream> #include <cstdio> #include <vector> #include <algorithm> #include <cstring> #include <queue> using namespace std; const int maxn = 1000; //顶点数,边数和源点 int n, m, src; //邻接矩阵 //g[i][j].first表示i节点的第j条边的节点编号 //g[i][j].second 表示边的长度. vector<pair<int, int> > g[maxn + 10]; //dist[i]表示源点src到i的距离 int dist[maxn + 10]; //是否在队列中 bool inQue[maxn + 10]; queue<int> que; void spfa() { memset(inQue, false, sizeof(inQue)); //初始化无穷大 memset(dist, 63, sizeof(dist)); //从src开始 dist[src] = 0; while(!que.empty()) que.pop(); que.push(src); inQue[src] = true; while(!que.empty()) { int u = que.front(); que.pop(); for(int i = 0; i < (int)g[u].size(); i++) { if(dist[u] + g[u][i].second < dist[g[u][i].first]) { dist[g[u][i].first] = dist[u] + g[u][i].second; if(!inQue[g[u][i].first]) { inQue[g[u][i].first] = true; que.push(g[u][i].first); } } } inQue[u] = false; } } int main() { while(scanf("%d%d", &n, &m) != EOF) { pair<int, int> path; int from; for(int i = 1; i <= m; i++) { scanf("%d%d%d", &from, &path.first, &path.second); g[from].push_back(path); swap(from, path.first); g[from].push_back(path); } src = 1; spfa(); for(int i = 1; i <= n; i++) { printf("d[%d] = %d\n", i, dist[i]); } } return 0; }
3。Prime算法
#include <iostream> #include <cstdio> #include <vector> #include <algorithm> #include <cstring> using namespace std; const int INF = 0x3fffffff; const int N = 1000; bool v ; int dist ; vector<pair<int, int> > g[N + 10]; int n, m;//顶点和边 int Prime() { //标记是否访问过 memset(v, 0, sizeof(v)); for(int i = 1; i <= N; i++) { dist[i] = INF; } //任找一个顶点,比如1 dist[1] = 0; int ans = 0; for(int i = 1; i <= n; ++i) { int mark = -1; for(int j = 1; j <= n; ++j) { if(!v[j]) { if(mark == -1) mark = j; else if(dist[j] < dist[mark]) mark = j; } } if(mark == -1) break; //标记为已经加入的节点 v[mark] = 1; ans += dist[mark]; for(int j = 0; j < (int)g[mark].size(); ++j) { if(!v[g[mark][j].first]) { int x = g[mark][j].first; dist[x] = min(dist[x], g[mark][j].second); } } } return ans; } int main() { while(scanf("%d%d", &n, &m) != EOF) { for(int i = 1; i <= n; i++) { g[i].clear(); } pair<int, int> path; int from; for(int i = 1; i <= m; i++) { scanf("%d%d%d", &from, &path.first, &path.second); g[from].push_back(path); swap(from, path.first); g[from].push_back(path); } int ans = Prime(); printf("ans = %d\n", ans); } return 0; }
4。Kruskal算法
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int maxn = 1000; const int maxm = 1000000; struct edge { int x, y, w; edge(int x = 0, int y = 0, int w = 0):x(x), y(y), w(w){} }e[maxm]; int fa[maxn]; int getfather(int x) { if(x == fa[x]) return x; return fa[x] = getfather(fa[x]); } //顶点和边 int n, m; bool cmp(edge a, edge b) { if(a.w < b.w) return true; return false; } int kruscal() { int ans = 0; sort(e, e+m, cmp); //初始为n个孤立的点 int cnt = n; for(int i = 1; i <= n; i++) { fa[i] = i; } for(int i = 0; i < m; i++) { int t1 = getfather(e[i].x); int t2 = getfather(e[i].y); if(t1 != t2) { fa[t1] = t2; //两个孤立部分合并之后减1 cnt--; ans += e[i].w; if(cnt == 1) break; } } return ans; } int main() { while(scanf("%d%d", &n, &m) != EOF) { for(int i = 0; i < m; i++) { scanf("%d%d%d", &e[i].x, &e[i].y, &e[i].w); } int ans = kruscal(); printf("ans = %d\n", ans); } return 0; }
相关文章推荐
- 图论, 1.各种方案的最短路径,最小生成树,拓扑排序, 2.隐式图的搜索,N-皇后问题,数独,马踏棋盘,中文划分,回文划分.
- Prim && Kruskal 生成MST(最小生成树)及最短路径问题
- 图论, 1.各种方案的最短路径,最小生成树,拓扑排序, 2.隐式图的搜索,N-皇后问题,数独,马踏棋盘,中文划分,回文划分.
- 图(二)——最小生成树、最短路径问题
- poj 1258 Agri-Net dijkstra迪杰斯特拉算法,最短路径问题的变形,最小生成树
- Kruskal 最小生成树 & Dijkstra 最短路径
- 最小生成树(prim&keluskal)最短路径(dijistra)
- 最小生成树&&最短路径
- 最小生成树&最短路径
- DS实验题 Floyd最短路径 & Prim最小生成树
- 最小生成树(prime算法 & kruskal算法)和 最短路径算法(floyd算法 & dijkstra算法)
- c语言之邻接矩阵&最短路径&最小生成树
- 算法篇-7-贪心算法-Huffman编码&Dijkstra单源最短路径&Kruskal最小生成树
- 数据结构-图-Java实现:有向图 图存储(邻接矩阵),最小生成树,广度深度遍历,图的连通性,最短路径
- 最小生成树(prime算法、kruskal算法) 和 最短路径算法(floyd、dijkstra)(转)
- 数据结构:图的存储、图的遍历、最小生成树、最短路径、拓扑排序
- 最小生成树(prime算法、kruskal算法) 和 最短路径算法(floyd、dijkstra)
- 最小生成树(prime算法、kruskal算法) 和 最短路径算法(floyd、dijkstra)
- NYOJ-38 布线问题(图论,最小生成树,Prime)
- 图论之最短路径(1)——Floyd Warshall & Dijkstra算法