HDOJ 1233 还是畅通工程(最小生成树)

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

还是畅通工程

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 32489    Accepted Submission(s): 14618


Problem Description
某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。
 

Input
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。
当N为0时,输入结束,该用例不被处理。
 

Output
对每个测试用例,在1行里输出最小的公路总长度。
 

Sample Input
31 2 11 3 22 3 441 2 11 3 41 4 12 3 32 4 23 4 50
 

Sample Output
35
Hint
Hint
Huge input, scanf is recommended.
 
 
 
最小生成树模板题。
 
Kruskal算法,代码如下:
 
<span style="font-size:12px;">#include<cstdio>#include<algorithm>using namespace std;int set[5000],n,m;struct node{int x,y,w;}row[5000];int cmp(node a,node b){return a.w<b.w;}int find(int x){int r=x,t;while(r!=set[r])   r=set[r];while(r!=x){t=set[x];set[x]=r;x=t;}return r;} int merge(int a,int b){int fa,fb;fa=find(a);fb=find(b);if(fa!=fb){set[fa]=fb;return 1;}return 0;}int main(){int i,sum;while(scanf("%d",&n)&&n){m=n*(n-1)/2;for(i=1;i<=n;i++)   set[i]=i;for(i=0;i<m;i++)  scanf("%d%d%d",&row[i].x,&row[i].y,&row[i].w);sort(row,row+m,cmp);sum=0;for(i=0;i<m;i++){if(merge(row[i].x,row[i].y))   sum+=row[i].w;}printf("%d\n",sum);}return 0;}</span>

 
 

 

prim算法,代码如下:

 

<span style="font-size:12px;">#include<cstdio>#include<cstring>#define INF 0x3f3f3f#define max 110int map[max][max],n,sum;void prim(){int next,i,j,min;sum=0;int lowcost[max],visit[max];memset(visit,0,sizeof(visit));for(i=1;i<=n;++i)   lowcost[i]=map[1][i];visit[1]=1;for(i=2;i<=n;++i){min=INF;for(j=1;j<=n;++j){if(!visit[j]&&min>lowcost[j]){min=lowcost[j];next=j;}}sum+=lowcost[next];visit[next]=1;for(j=1;j<=n;++j){if(!visit[j]&&lowcost[j]>map[next][j])lowcost[j]=map[next][j];}}}int main(){int m,i,x,y,c;while(scanf("%d",&n)&&n){m=n*(n-1)/2;while(m--){scanf("%d%d%d",&x,&y,&c);map[x][y]=map[y][x]=c;}prim();printf("%d\n",sum);}return 0;} </span>


 


0 0
原创粉丝点击