hdu1863 畅通工程 Kruskal 和 Prime求最小生成树
来源:互联网 发布:linux vi怎么保存 编辑:程序博客网 时间:2024/05/18 03:54
畅通工程
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 26667 Accepted Submission(s): 11655
Problem Description
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。
Input
测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M ( < 100 );随后的 N
行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。
行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。
Output
对每个测试用例,在1行里输出全省畅通需要的最低成本。若统计数据不足以保证畅通,则输出“?”。
Sample Input
3 31 2 11 3 22 3 41 32 3 20 100
Sample Output
3?
Source
浙大计算机研究生复试上机考试-2007年
两个算法都用来求最小生成树。。。
zyyyyy之前在天黑板(滑稽)上讲过Kruskal算法,即对所有的边根据花费来排个序,然后利用并查集每次贪心地选最小的边加入当前的最小生成树。
Kruskal版本:
#include <iostream>#include <string>#include <cstdio>#include <algorithm>#include <vector>#include <queue>#include <cmath>using namespace std;const int maxn = 110;int n,m;int father[maxn];struct unit { int from,to; long long cost;}save[maxn*maxn];bool compare(unit a,unit b){ return a.cost<b.cost;}int find(int x){ if(x==father[x]) return x; return father[x] = find(father[x]);}bool isConnected(int a,int b){ return find(a) == find(b);}void mix(int a,int b){ int u = find(a),v = find(b); if(u==v){ return ; } father[u] = v;}long long Kruskal(){ long long result = 0; sort(save+1, save+1+m, compare); for(int i =1 ;i<=m;i++){ if(isConnected(save[i].from, save[i].to)){ continue; } mix(save[i].from, save[i].to); result += save[i].cost; } return result;}int main(){ while(scanf("%d%d",&m,&n)&&m){ int i; for(i=1;i<=n;i++){ father[i]=i; } for(i=1;i<=m;i++){ scanf("%d%d%lld",&save[i].from,&save[i].to,&save[i].cost); } bool flag = true; long long result = Kruskal(); for(i=1;i<=n;i++){ if(!isConnected(1, i)){ flag = false; } } if(flag){ printf("%lld\n",result); }else{ printf("?\n"); } } return 0;}
而Prime算法好像更复杂一点?想法和Kruskal差不多
利用优先队列来储存每个点连接的边,程序一开始,随机地选择一个点作为起点,每次都是选择和这条边相连并且没有访问过的点的最短的边加入最小生成树,然后标记这些访问过的点。
Prime版本:
#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>#include <vector>#include <queue>#include <cmath>using namespace std;const int maxn = 110;int n,m;int father[maxn];struct unit { int from,to; long long cost; bool operator < (const unit &a)const{ return a.cost<cost; }};priority_queue<unit> que;vector<unit> cost[maxn];bool vis[maxn];//is visited?long long Prime(){ long long result = 0; vis[1] =true; int i; for(i=0;i<cost[1].size();i++){ que.push(cost[1][i]); } while(que.size()){ unit now = que.top(); que.pop(); if(!vis[now.to]){ result += now.cost; vis[now.to] = true; for(i=0;i<cost[now.to].size();i++){ que.push(cost[now.to][i]); } } } return result;}int main(){ while(scanf("%d%d",&m,&n)&&m){ int i; for(i=1;i<=n;i++){ cost[i].clear(); } memset(vis, false, sizeof(vis)); while(que.size()){ que.pop(); } for(i=1;i<=m;i++){ unit now; scanf("%d%d%lld",&now.from,&now.to,&now.cost); cost[now.from].push_back(now); } bool flag = true; long long result = Prime(); for(i=1;i<=n;i++){ if(!vis[i]){ flag = false; } } if(flag){ printf("%lld\n",result); }else{ printf("?\n"); } } return 0;}
0 0
- hdu1863 畅通工程 Kruskal 和 Prime求最小生成树
- 最小生成树 Kruskal hdu1863 畅通工程
- Kruskal & Prim 最小生成树HDU1863 畅通工程
- hdu1863畅通工程 最小生成树 Kruskal算法
- hdu1863-畅通工程(Prime & Kruskal)
- 最小生成树Prime算法(hdu1233还是畅通工程 、hdu1863畅通工程)
- hdu1863 畅通工程(最小生成树)
- Hdu1863 - 畅通工程 - 最小生成树
- HDU1863 畅通工程 【最小生成树Prim】
- hdu1863-畅通工程-最小生成树
- HDU1863 畅通工程 最小生成树
- hdu1863畅通工程【最小生成树】
- hdu1863畅通工程(最小生成树)
- HDU1863畅通工程(最小生成树)
- HDU1863 畅通工程 最小生成树
- HDU1863 畅通工程 【图论】【最小生成树】
- 最小生成树:HDU1863-畅通工程
- 【HDU1863】畅通工程(最小生成树)
- 实战学习NodeJS建站(5)—nodejs 访问 redis
- 字符串函数strlen
- ubuntu下 用mentohust代替锐捷认证上网
- window.open()参数传递及获取
- RAC环境下的备份与恢复(一)
- hdu1863 畅通工程 Kruskal 和 Prime求最小生成树
- c++ lambda表达式笔记
- 压缩感知测量矩阵详解
- 51Nod-1022-石子归并 V2
- 小笔记-用位运算实现求平均数的一个较高效方法
- Android练习-----计时器(Chronometer)
- UOJ 207 共价大爷游长沙
- JavaScript基础_03样式引入与结构语句
- ORA获取服务名