hdu_1233 还是畅通工程

来源:互联网 发布:matlab数据周期性检验 编辑:程序博客网 时间:2024/05/18 01:52

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1233

原题描述:

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

分析:

        使用kruskal算法求最小生成树,这里用幷查集查看选中的边是否构成环。

我的代码:

#include<stdio.h>#include<algorithm>using namespace std;const int MAXN=5000;struct Node{    int a,b,v;    bool operator < (const Node& x) const    {        return v<x.v;    }}p[MAXN];int f[120]; //用并查集判断点是否构成了环。int r[120];void init(){    for(int i=1;i<120;i++)    {        f[i]=i;        r[i]=1;    }}int find(int x){    if(x==f[x]) return x;    else  return f[x]=find(f[x]);}void Union(int a,int b){    a=find(a);    b=find(b);    if(a==b) return ;    else{        if(r[a]<r[b])        {            f[a]=b;            r[b]+=r[a];        }        else        {            f[b]=a;            r[a]+=r[b];        }    }}int main(){    int n;    while(~scanf("%d",&n)&&n)    {        int N=n*(n-1)/2;        for(int i=0;i<N;i++)        {            scanf("%d%d%d",&p[i].a,&p[i].b,&p[i].v);        }        sort(p,p+N);        int ans=0;        init();        for(int i=0;i<N;i++)        {            int a=find(p[i].a);            int b=find(p[i].b);            if(a!=b)            {                ans+=p[i].v;                Union(a,b);            }        }        printf("%d\n",ans);    }    return 0;}
总结:突然在想,好像直接用数组标记点用过没有,来判断是否构成环会更简单吧-,-,今天发现用数组这样标记是不行的,是否用过和构成环不是一样的..


原创粉丝点击