nyoj 118 修路方案(次小生成树)
2015-09-29 09:25
176 查看
修路方案
时间限制:3000 ms | 内存限制:65535 KB难度:5
描述
南将军率领着许多部队,它们分别驻扎在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)
样例输入
2 3 3 1 2 1 2 3 2 3 1 3 4 4 1 2 2 2 3 2 3 4 2 4 1 2
样例输出
No Yes
来源POJ题目改编
上传者
张云聪
次小生成树,算法思路:
先求出最小生成树,记录值和边,然后依次每次删除这些边中的一条,用再求最小生成树
算出来的值找出最小的就是次小生成树的值。
这题只需要比较每次新建的最小生成树的值是否和原来最小生成树的值是否一样就可以了。
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define inf 0x3f3f3f3f const int M=510; const int N=210000; struct node{ int s,e,w,vis; }mp ; int x[M],n,m; bool cmp(node a,node b){ return a.w<b.w; } void init(){ for(int i=0; i<M; ++i) x[i] = i; } int Find(int k){ if(x[k]==k) return k; x[k]=Find(x[k]); //压缩路径 return x[k]; } int LT(){ //判断图是否连通 int t=Find(1); for(int i=2;i<=n;++i){ if(Find(i) != t) return 0; } return 1; } int judge(int n){ int sum=0; for(int i=0;i<m;++i){ if(i!=n){ // 删除这条边再求最小生成树 int fa=Find(mp[i].s); int fb=Find(mp[i].e); if(fa!=fb){ sum+=mp[i].w; x[fb]=fa; } } } if( LT() ) return sum; return -1; } int main(){ int t; int a,b,c; scanf("%d", &t); while(t--){ init(); scanf("%d%d",&n,&m); for(int i=0; i<m; ++i){ scanf("%d%d%d",&a,&b,&c); mp[i].s = a; mp[i].e = b; mp[i].w = c; mp[i].vis=0; } int sum=0,mx=0; sort(mp,mp+m,cmp); for(int i=0; i<m; ++i){ int A=Find(mp[i].s); int B=Find(mp[i].e); if(A!=B){ x[B]=A; sum+=mp[i].w; mp[i].vis=1; } } int ok=0; for(int i=0; i<m; ++i){ if(mp[i].vis == 1){ init(); //注意每次的初始化 if(judge(i) == sum){ ok=1; break; } } } if(ok) printf("Yes\n"); else printf("No\n"); } return 0; }
相关文章推荐
- Android系统之Phone模块-接电话Unsolicited消息的接收和处理过程
- Hibernate项目报错,提示有文件删不掉或是无法找到等,解决方法见正文
- 解耦传值的问题
- c 实现的shell
- 黑马程序员——C语言基础---数组1
- 修改Linux最大连接数
- 反渗透设备:反渗透设备回收率高
- 黑马程序员学习(十五) 多线程
- iOS开发-------地图定位显示周围微博(CLLocationManager 定位管理)
- java使用poi处理excel防止数字变成科学计数法的形式
- C#程序实现动态调用DLL的研究
- 上机实践 - - 一个例子了解C/C++中指针与数组的区别
- iOS9新特性及适配教程
- DNS服务之DNS基础
- Java 字符的验证
- Opengl Intro - glViewport
- TelephonyManager类的方法详解
- LeetCode Number of 1 Bits
- BZOJ 1483 [HNOI2009]梦幻布丁 链式前向星+启发式合并
- 反渗透设备:反渗透设备工艺先进