POJ1797 Heavy Transportation (最短路径/最小生成树kruskal)
2014-10-17 00:00
337 查看
本文出自:http://blog.csdn.net/svitter
原题连接:http://poj.org/problem?id=1797
题意:找出一条从1 ~ n的所有的路径中权值最小的那条路径,然后找出其中权值最大的边。
看了吉大的指导才用最小生成树的心态去做,其实压根没读明白题目。。这个题目可以用最小生成树的心态去解,因为是找最短的路径。krus中灵活运用了并查集的思想,所以在这里面,如果1, n在同一个集合中,也就找到了最短的路径,然后因为按照边的长短依此加入的,因此,使find(1) == find(n)成立加入的最后一条边,即为所求。
原题连接:http://poj.org/problem?id=1797
题意:找出一条从1 ~ n的所有的路径中权值最小的那条路径,然后找出其中权值最大的边。
看了吉大的指导才用最小生成树的心态去做,其实压根没读明白题目。。这个题目可以用最小生成树的心态去解,因为是找最短的路径。krus中灵活运用了并查集的思想,所以在这里面,如果1, n在同一个集合中,也就找到了最短的路径,然后因为按照边的长短依此加入的,因此,使find(1) == find(n)成立加入的最后一条边,即为所求。
#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; int p[1005];//集合的数组 int r[1005];//按秩 int m, n; // int find(int v) { if(v != p[v]) p[v] = find(p[v]); return p[v]; } void join(int u, int v) { int a = find(u); int b = find(v); if(a == b) return; if(r[a] < r[b]) { p[a] = b; } else if(r[a] > r[b]) { p[b] = a; } else { p[a] = b; r[b] ++; } } void init_set() { int i; for(i = 1; i <= n; i++) { p[i] = i; r[i] = 1; } } struct Edge { int u; int v; int weight; }; struct Edge edge[1000005]; void quick_sort(struct Edge * start, struct Edge * end) { if(start >= end) return; struct Edge* loc = start; struct Edge* iterator; struct Edge tmp; for(iterator = start; iterator != end; iterator++) { if(iterator -> weight < (end - 1) -> weight) //按从小到大的顺序排列, 决定是最小还是 { tmp = *loc; *loc = *iterator; *iterator = tmp; loc++; } } tmp = *loc; *loc = *(end - 1); *(end - 1) = tmp; quick_sort(start, loc); quick_sort(loc + 1, end); } bool cmp(Edge e1, Edge e2) { return e1.weight > e2.weight; } int kru() { init_set(); //quick_sort(edge, edge+m); sort(edge, edge + m, cmp); int i; for(i = 0; i < m; i++) { int u = edge[i].u; int v = edge[i].v; //如果两个顶点不在一个集合中,则不会生成环,于是该边被加入生成树 if(find(u) != find(v)) { join(u, v); } if(find(1) == find(n)) { return edge[i].weight; } } return edge[i].weight; } void ace() { int Case, no = 1; int ret, i; //freopen("test.txt", "r", stdin); scanf("%d", &Case); for(no = 1; no <= Case; no++) { scanf("%d%d", &n, &m); for(i = 0; i < m; i++) { scanf("%d%d%d", &edge[i].u, &edge[i].v, &edge[i].weight); } ret = kru(); printf("Scenario #%d:\n%d\n\n", no, ret); } } int main() { ace(); return 0; }
相关文章推荐
- POJ1797 Heavy Transportation (最短路径/最小生成树kruskal)
- POJ1797 Heavy Transportation (最短路径/最小生成树kruskal)
- 最小生成树算法(Prime、Kruskal)和最短路径算法(Dijkstra、Floyd)
- C++实现矩阵图的遍历·最小生成树(prim,kruskal)·最短路径(Dijkstra,floyd)
- 稀疏图(邻接链表),并查集,最短路径(Dijkstra,spfa),最小生成树(kruskal,prim)
- Kruskal 最小生成树 & Dijkstra 最短路径
- 图(Graph)——最小生成树、最短路径、Kruskal、Dijkstra、Floyd
- 算法篇-7-贪心算法-Huffman编码&Dijkstra单源最短路径&Kruskal最小生成树
- 稠密图(邻接矩阵),并查集,最短路径(Dijkstra,spfa),最小生成树(kruskal,prim)
- 浅析最小生成树和单源最短路径的区别(含Prim、Kruskal、Dijkstra、Bellman-Ford)
- Prim && Kruskal 生成MST(最小生成树)及最短路径问题
- 关于图的常用算法——Dijkstra单源最短路径、Floyd多源最短路径、Prim和Kruskal最小生成树算法
- 最小生成树,最短路径的基本算法
- 最小生成树,最短路径算法
- C数据结构(文件操作,随机数,排序,栈和队列,图和遍历,最小生成树,最短路径)程序例子
- 最小生成树_AOV网(拓扑排序)_AOE网(关键路径)_最短路径
- 图(有向图,无向图)的邻接矩阵表示C++实现(遍历,拓扑排序,最短路径,最小生成树) Implement of digraph and undigraph using adjacency matrix
- 图的周游,最短路径和最小生成树
- 最小生成树Prim算法和单源最短路径Dijkstra算法
- dijkstra最短路径算法和普里姆最小生成树算法优化的关键