hdoj 1863 畅通工程 【最小生成树】

来源:互联网 发布:儿童学编程 编辑:程序博客网 时间:2024/05/16 03:36

畅通工程

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 21322    Accepted Submission(s): 9170


Problem Description
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。
 

Input
测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M ( < 100 );随后的 N
行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。
 

Output
对每个测试用例,在1行里输出全省畅通需要的最低成本。若统计数据不足以保证畅通,则输出“?”。
 

Sample Input
3 31 2 11 3 22 3 41 32 3 20 100
 

Sample Output
3?
 

思路:求最小生成树,如果最小生成树中的元素等于总村庄数就输出sum(最小成本),否则未畅通,输出"?"。


代码:

Kruskal算法:

 

#include<stdio.h>#include<algorithm>using namespace std;int n,m;int per[110];struct record{int s,e,w;}num[10000];bool cmp(record a,record b){return a.w<b.w;}int init(){for(int i=1;i<=m;i++){per[i]=i;}}int find(int x){int r;r=x;while(r!=per[r]){r=per[r];}per[x]=r;return r;}int join(int x,int y){int fx=find(x);int fy=find(y);if(fx!=fy){per[fx]=fy;return true;}return false;}int main(){int i;while(scanf("%d%d",&n,&m)!=EOF&&n){for(i=0;i<n;i++){scanf("%d%d%d",&num[i].s,&num[i].e,&num[i].w);}sort(num,num+n,cmp);init();int sum=0,f=1;for(i=0;i<n;i++){if(join(num[i].s,num[i].e)){sum+=num[i].w;f++;}}if(f==m){printf("%d\n",sum);}else{printf("?\n");}}return 0;}


 Prim算法:

#include<stdio.h>#include<string.h>#define INF 0x3f3f3fint map[110][110];int vis[110];int lowcost[110];int n;void prim(){    int sum=0,i,j,min,next;memset(vis,0,sizeof(vis));for(i=1;i<=n;i++){lowcost[i]=map[1][i];}vis[1]=1;for(i=2;i<=n;i++){min=INF;for(j=1;j<=n;j++){if(!vis[j]&&min>lowcost[j]){min=lowcost[j];next=j;}}if(min==INF){printf("?\n");return ;}sum+=min;vis[next]=1;for(j=1;j<=n;j++){if(!vis[j]&&lowcost[j]>map[next][j]){lowcost[j]=map[next][j];}}}printf("%d\n",sum);}int main(){int i,m,a,b,c;while(scanf("%d%d",&m,&n)!=EOF&&m){memset(map,INF,sizeof(map));for(i=0;i<m;i++){scanf("%d%d%d",&a,&b,&c);map[a][b]=map[b][a]=c;}prim();}return 0;}


 

0 0