描述

南将军率领着许多部队,它们分别驻扎在N个不同的城市里,这些城市分别编号1~N,由于交通不太便利,南将军准备修路。

现在已经知道哪些城市之间可以修路,如果修路,花费是多少。

现在,军师小工已经找到了一种修路的方案,能够使各个城市都联通起来,而且花费最少。

但是,南将军说,这个修路方案所拼成的图案很不吉利,想让小工计算一下是否存在另外一种方案花费和刚才的方案一样,现在你来帮小工写一个程序算一下吧。

 
输入
第一行输入一个整数T(1<T<20),表示测试数据的组数
每组测试数据的第一行是两个整数V,E,(3<V<500,10<E<200000)分别表示城市的个数和城市之间路的条数。数据保证所有的城市都有路相连。
随后的E行,每行有三个数字A B L,表示A号城市与B号城市之间修路花费为L。
输出
对于每组测试数据输出Yes或No(如果存在两种以上的最小花费方案则输出Yes,如果最小花费的方案只有一种,则输出No)
样例输入
  1. 2
  2. 3 3
  3. 1 2 1
  4. 2 3 2
  5. 3 1 3
  6. 4 4
  7. 1 2 2
  8. 2 3 2
  9. 3 4 2
  10. 4 1 2
样例输出
  1. No
  2. Yes
来源
POJ题目改编
上传者
张云聪

题意:次小生成树

WA代码:

  1. #include <vector>
  2. #include <map>
  3. #include <set>
  4. #include <algorithm>
  5. #include <iostream>
  6. #include <cstdio>
  7. #include <cmath>
  8. #include <cstdlib>
  9. #include <string>
  10. #include <cstring>
  11. #include <queue>
  12. using namespace std;
  13.  
  14. #define MAX 200020
  15. #define INF 0x3f3f3f3f
  16.  
  17. struct edge
  18. {
  19. int x,y,cost;
  20. int flag;
  21. };
  22.  
  23. edge e[MAX];
  24. int f[MAX];
  25. int dis[MAX];
  26. int v,n,m,ans;
  27.  
  28. bool cmp(edge a,edge b)
  29. {
  30. return a.cost<b.cost;
  31. }
  32.  
  33. void init(int n)
  34. {
  35. for(int i=;i<=n;i++)
  36. f[i]=i;
  37. }
  38.  
  39. int find(int x)
  40. {
  41. if(x!=f[x])
  42. f[x]=find(f[x]);
  43. return f[x];
  44. }
  45.  
  46. void Union(int x,int y)
  47. {
  48. x=find(x);
  49. y=find(y);
  50. f[y]=x;
  51. }
  52.  
  53. int same(int x,int y)
  54. {
  55. return find(x)==find(y);
  56. }
  57.  
  58. int kruskal_1(int n,int m)
  59. {
  60. int ans=;
  61. for(int i=;i<m;i++)
  62. {
  63. if(!same(e[i].x,e[i].y))
  64. {
  65. e[i].flag=;
  66. Union(e[i].x,e[i].y);
  67. ans+=e[i].cost;
  68. }
  69. }
  70. return ans;
  71. }
  72.  
  73. int kruskal_2(int n,int m)
  74. {
  75. int ans=,cnt=;
  76. for(int i=;i<m;i++)
  77. {
  78. if (i == n)//除去这条边之后再求一次最小生成树
  79. continue;
  80. if(!same(e[i].x,e[i].y))
  81. {
  82. Union(e[i].x,e[i].y);
  83. ans+=e[i].cost;
  84. cnt++;
  85. }
  86. }
  87. if(cnt!=n)
  88. return -;
  89. else
  90. return ans;
  91. }
  92.  
  93. int main()
  94. {
  95. int t;
  96. scanf("%d",&t);
  97. while(t--){
  98. init(n);
  99. memset(e,,sizeof(e));
  100. int v=;
  101. scanf("%d%d",&n,&m);
  102. int count;
  103. for(int i=; i<m; i++){
  104. scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].cost);
  105. e[i].flag=;
  106. }
  107. sort(e,e+m,cmp);
  108. int flag=,prim_2;
  109. int prim_1=;
  110.  
  111. prim_1=kruskal_1(n,m);
  112. /*for(int i=0; i<m; i++){
  113. cout<<e[i].x<<e[i].y<<e[i].cost<<e[i].flag<<endl;
  114. }*/
  115.  
  116. for(int i=; i<m; i++){
  117. if(e[i].flag==)
  118. continue;
  119. prim_2=;
  120. init(n);
  121. prim_2=kruskal_2(i,m);
  122. if(prim_2==prim_1){
  123. flag=;
  124. break;
  125. }
  126. }
  127.  
  128. if(prim_1==prim_2){
  129. flag=;
  130. }
  131.  
  132. if(flag)
  133. printf("Yes\n");
  134. else
  135. printf("No\n");
  136. }
  137. }

AC代码:

  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<algorithm>
  4. using namespace std;
  5. struct node
  6. {
  7. int u,v,val;
  8. int flog;
  9. }edge[+];
  10. int pre[],m,n,minn;
  11. void init()
  12. {
  13. for(int i=;i<;i++)
  14. pre[i]=i;
  15. }
  16. int cmp(node s1,node s2)
  17. {
  18. return s1.val<s2.val;
  19. }
  20. int find(int x)
  21. {
  22. return pre[x]==x?x:pre[x]=find(pre[x]);
  23. }
  24. int F(int w)
  25. {
  26. int sum=;
  27. for(int i=;i<m;i++)
  28. {
  29. if(i!=w)
  30. {
  31. int fx=find(edge[i].u);
  32. int fy=find(edge[i].v);
  33. if(fx!=fy)
  34. {
  35. pre[fx]=fy;
  36. sum+=edge[i].val;
  37. }
  38. }
  39. }
  40. int s=find();//判断全部的点是不是已经全部连进去
  41. for(int i=;i<=n;i++)
  42. if(pre[i]!=s)
  43. return -;
  44. return sum;
  45. }
  46. int main()
  47. {
  48. int t;
  49. scanf("%d",&t);
  50. while(t--)
  51. {
  52. init();
  53. scanf("%d%d",&n,&m);
  54. for(int i=;i<m;i++)
  55. scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].val),edge[i].flog=;
  56. sort(edge,edge+m,cmp);
  57. minn=;
  58. for(int i=;i<m;i++)//找到最小生成树
  59. {
  60. int fx=find(edge[i].u);
  61. int fy=find(edge[i].v);
  62. if(fx!=fy)
  63. {
  64. pre[fx]=fy;
  65. edge[i].flog=;//标记这条边在最小生成树中已经用过
  66. minn+=edge[i].val;
  67. }
  68. }
  69. int flag=;
  70. for(int i=;i<m;i++)
  71. {
  72. if(edge[i].flog)//每次排除一条边
  73. {
  74. init();
  75. if(F(i)==minn)
  76. {
  77. flag=;
  78. break;
  79. }
  80. }
  81. if(flag) break;
  82. }
  83. if(flag) printf("Yes\n");
  84. else printf("No\n");
  85. }
  86. return ;
  87. }

Nyoj 修路方案(次小生成树)的更多相关文章

  1. hdu4081 秦始皇修路(次小生成树)

    题目ID:hdu4081   秦始皇修路 题目链接:点击打开链接 题目大意:给你若干个坐标,每个坐标表示一个城市,每个城市有若干个人,现在要修路,即建一个生成树,然后有一个魔法师可以免费造路(不消耗人 ...

  2. nyoj_118:修路方案(次小生成树)

    题目链接 题意,判断次小生成树与最小生成树的权值和是否相等. 豆丁文档-- A-star和第k短路和次小生成树和Yen和MPS寻路算法 法一: 先求一次最小生成树,将这棵树上的边加入一个向量中,再判断 ...

  3. 修路方案 Kruskal 之 次小生成树

    次小生成树 : Kruskal 是先求出来  最小生成树 , 并且记录下来所用到的的边 , 然后再求每次都 去掉最小生成树中的一个边 , 这样求最小生成树 , 然后看能不能得到 和原来最小生成树一样的 ...

  4. 修路方案(nyoj)

    算法:次小生成树 描述 南将军率领着许多部队,它们分别驻扎在N个不同的城市里,这些城市分别编号1~N,由于交通不太便利,南将军准备修路. 现在已经知道哪些城市之间可以修路,如果修路,花费是多少. 现在 ...

  5. NYOJ 118 修路方案

    修路方案 时间限制:3000 ms  |  内存限制:65535 KB 难度:5   描述 南将军率领着许多部队,它们分别驻扎在N个不同的城市里,这些城市分别编号1~N,由于交通不太便利,南将军准备修 ...

  6. nyoj--118--修路方案(次小生成树)

    修路方案 时间限制:3000 ms  |  内存限制:65535 KB 难度:5 描述 南将军率领着许多部队,它们分别驻扎在N个不同的城市里,这些城市分别编号1~N,由于交通不太便利,南将军准备修路. ...

  7. nyoj 118 修路方案(最小生成树删边求多个最小生成树)

    修路方案 时间限制:3000 ms  |  内存限制:65535 KB 难度:5   描述 南将军率领着许多部队,它们分别驻扎在N个不同的城市里,这些城市分别编号1~N,由于交通不太便利,南将军准备修 ...

  8. hdu4081 次小生成树变形

    pid=4081">http://acm.hdu.edu.cn/showproblem.php?pid=4081 Problem Description During the Warr ...

  9. HDU 4081 Qin Shi Huang's National Road System 次小生成树变种

    Qin Shi Huang's National Road System Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/3 ...

随机推荐

  1. 使用 Gradle 插件进行代码分析(转)

    代码分析在大多数项目中通常是作为最后一个步骤(如果做了的话)完成的.其通常难以配置及与现有代码整合. 本文旨在勾勒出使用 Gradle 整合 PMD 与 FindBugs 的步骤,并将其与一个现有的 ...

  2. 揭秘传智播客毕业班的超级薪水7k内幕系列II----Offer工资表5.7k,为什么不能让老师就业就业

    在上海传智播客宋学生Java六期学员.在班级尚未毕业阶段,私自投递简历,而且逃课去面试,获得某国企的Offer.入职薪资5.7K,,兼有五险一金.饭补等齐全福利,因就业老师要求班级同学未毕业不要急于就 ...

  3. 从零开始做UI-静电的sketch设计教室 视频教程

    全套31集目录 01-初识Sketch  http://www.ui.cn/detail/52223.html02-sketch的下载与安装  http://www.ui.cn/detail/5222 ...

  4. C#中的Virtual

    在 C# 中,派生类可以包含与基类方法同名的方法. 基类方法必须定义为 virtual. 如果派生类中的方法前面没有 new 或 override 关键字,则编译器将发出警告,该方法将有如存在 new ...

  5. HTC M7日文版HTL22刷机包 毒蛇2.5.0 ART NFC Sense6.0

    ROM介绍 日文版的蝰蛇2.5.0简短的介绍: *根据最新的M8蝰蛇版本号2.5.0 *经过我的朋友和机器测试.功能是否正常,当然,并非所有的功能进行测试,以,假设遇到BUG请反馈 *删除国外社会.谷 ...

  6. 【C语言探索之旅】 第一部分第四课第二章:变量的世界之变量声明

    内容简介 1.课程大纲 2.第一部分第四课第二章:变量的世界之变量声明 3.第一部分第四课第三章预告:变量的世界之显示变量内容 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布 ...

  7. JCombox

    A component that combines a button or editable field and a drop-down list. The user can select a val ...

  8. SQL Server数据库附加失败:错误5120和错误950

    再次敲机房,想參考曾经的物理模型,结果在附加数据库这一环节出现了点问题,以下总结一下. 1.附加数据库失败,错误5120 对于这样的错误,我在网上搜集了一下,主要有下面几种解决的方法: 方法一:将要附 ...

  9. HDU 2063:过山车(偶匹配,匈牙利算法)

    过山车 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submis ...

  10. 软体project(两)——软体project

        每本书的第一章,都是在讲宏观的东西.软工也不例外.接下来.我们就要介绍软件project"是什么"的问题. 一.是什么? watermark/2/text/aHR0cDov ...