您的位置:首页 > 其它

hdoj畅通工程

2015-08-11 11:01 246 查看

畅通工程

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 21340    Accepted Submission(s): 9180


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

 

[align=left]Input[/align]
测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M ( < 100 );随后的 N

行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。

 

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

 

[align=left]Sample Input[/align]

3 3
1 2 1
1 3 2
2 3 4
1 3
2 3 2
0 100

 

[align=left]Sample Output[/align]

3
?

 

本题考察最小生成树,也就是说各个节点距离的总和最小,用的克鲁斯卡尔算法,但是基础是并查集的内容,首先我们要思考,树不能有环,把并的函数稍微修改一下,返回真假值,给每个节点之间的距离用sort排序,我们定义的结构体两个村庄的编号,和两村庄之间距离。用sum盛放生成树的距离总和,最后再判断一下,他每个节点是否连通,也就是说他的根是否是一,如果是输出结果,如果不是输出?。以下是我所写代码。

#include<stdio.h>

#include<algorithm>

using namespace std;

int p[120],n,m;//定义村庄编号数组

struct node//定义一个结构体数组来存放两村庄编号和道路的距离

{

 int s,q,t;

}c[100];

void f1()//给村庄编号数组初始化

{

 for(int i=1;i<=m;i++)

 p[i]=i;

}

int cmp(const node &a,const node &b)//快速排序的cmp函数

{

 return a.t<b.t;

}

int f(int x)//查找根

{

 int r=x;

 while (r!=p[r])

 r=p[r];

 return r;

}

int fine(int x,int y)//并

{

 int a,b;

 a=f(x);

 b=f(y);

 if(a!=b)

 {

 p[b]=a;

 return 1;//返回真主要判断是否是环

    }

    else

    return 0;//返回假

 

}

int main()

{

 while(scanf("%d%d",&n,&m)!=EOF&&n)

 {

  int sum=0,z=0;

  for(int i=0;i<n;i++)

  scanf("%d%d%d",&c[i].s,&c[i].q,&c[i].t);

  sort(c,c+n,cmp);//给道路距离排序

  f1();

  for(int i=0;i<n;i++)

  if(fine(c[i].s,c[i].q))

  sum=sum+c[i].t;

  for(int i=1;i<=m;i++)

  if(p[i]==i)//判断根的个数

  z++;

  if(z>1)

  printf("?\n");

  else

  printf("%d\n",sum);

  

 }

 return 0;

}

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: