hud-1863-畅通工程(最小生成树)

来源:互联网 发布:pc护眼软件 编辑:程序博客网 时间:2024/06/18 11:48
畅通工程
Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 21225    Accepted Submission(s): 9138




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


 


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


 


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


 


Sample Input
3 3
1 2 1
1 3 2
2 3 4
1 3
2 3 2
0 100
 


Sample Output
3

?

//hdu-1863-畅通工程(最小生成树-克鲁是卡尔)//题目大意:有m个村庄,给出n条评估道路数,//问你能不能从这些路中选出几条使修路的费用最小;//若能,打印出最小费用,若否,打印“?”;//解题思路://本题属于最小生成树问题,运用克鲁斯卡尔算法求出最小生成树//首先,定义数组 per[110],用来存放村庄(即顶点),定义结构体数组//dalu[5000]用来存放评估道路的起点、终点、费用; //解决本题的关键就是连接函数link()的定义;//传入两个节点判断其是否在同一根节点上,若是,返回假//(表示此两点会构成环,不能相连),若否,可以相连,返回真; // 经过排序之后,通过主函数中的if对费用累加得到的就是最小费用//当然,上述是只有当根节点有一个时,才会成立,否则,道路就非联通,打印"?" #include<cstdio>#include<algorithm>using namespace std;int per[110];int n,m;struct node{int stat;int end;int price;}dlu[5000];int cmp(node x,node y){return x.price<y.price;}int init(){int i;for(i=1;i<=m;i++)  per[i]=i;}int find(int x){int r=x;while(r!=per[r])  r=per[r];return r;}bool link(int x,int y){int fx=find(x),fy=find(y);if(fx!=fy){      //判断是否成环,是-返回假,否-返回真; per[fx]=fy;return true;}return false;}int main(){int j,sum,cnt;while(scanf("%d%d",&n,&m),n){sum=0;init();for(j=0;j<n;j++)  scanf("%d%d%d",&dlu[j].stat,&dlu[j].end,&dlu[j].price);sort(dlu,dlu+n,cmp);//对费用升序排序; for(j=0;j<n;j++){if(link(dlu[j].stat,dlu[j].end))  sum+=dlu[j].price;}for(j=1,cnt=0;j<=m;j++)//统计根节点的数目;   if(j==per[j])    cnt++;if(cnt>1)  printf("?\n");else  printf("%d\n",sum);   }return 0;}
当然,最后的判定道路是否联通可以优化一下,即不用 cnt 统计根节点的数目,而是在连接顶点的时候判断最后能否构成最小生成树,若是,那么打印出最小费用,若否,打印

“?”即可;代码如下:

sort排序开始:             sort ( dlu, dlu + n, cmp );

                                    for ( j = 0 cnt = 0;j < n; j + +) {

                                          if ( link ( dlu [ j ].start, dlu [ j ].end)

                                          {

                                                      sum+=dlu [ j ].price;

                                                      cnt + +;

                                              }

                                    }

                                   if ( cnt == n-1 )

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

                                   else

                                            printf( "?\n" );                                                      

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 手机被标记骚扰电话怎么办 360摄像头不支持5g怎么办 摄像头不支持5g网络怎么办 家里的wifi卡了怎么办 办信用卡没有座机号码怎么办 拨打电话时显示号码有误怎么办 个体营业执照怎么办企业支付宝 没满16岁怎么办电话卡 我的电话卡丢了怎么办 公司注销地税没有补齐怎么办 公司没有固定电话怎么办信用卡 申请信用卡公司没有固定电话怎么办 办理信用卡公司没有固定电话怎么办 江门市固话欠费停机后怎么办 物业交钥匙地面有裂缝怎么办 深圳交通卡丢了怎么办 没装etc走etc怎么办 找不到过敏源身体痒怎么办 微信客服电话打不通怎么办 华为手机网络信号不好怎么办 酷我好友动态加载不了怎么办? 米兔电话手表停机了怎么办 糖猫电话手表停机了怎么办 360电话手表停机了怎么办 小天才电话手表停机怎么办 移动手机卡不知道号码怎么办 天猫退款手机号换了怎么办 科目二考试脚抖怎么办 面试新工作没打电话怎么办 怀孕5个月胎位低怎么办 做业务很害怕打电话怎么办 固定电话总是接到骚扰电话怎么办 电话卡通话被限制了怎么办? 手机名单拉黑了怎么办 被苹果6s被拉黑怎么办 重庆福利企业解聘残疾职工怎么办 被银行拉入黑名单怎么办 借的钱还不起了怎么办 支付宝手机号空号了怎么办 到处贷不到钱了怎么办 还不起钱借不到怎么办