NYOJ 118 Prim求次小生成树
2016-07-20 12:11
183 查看
传送门
思路:
这里用Maxlen记录在最小生成树里的点两点之间存在的最大的权值边,
然后枚举每条没有加入的边,如果有很这两点之间在最小生成树里的最大边相等的,就说明有次小生成树。
思路:
这里用Maxlen记录在最小生成树里的点两点之间存在的最大的权值边,
然后枚举每条没有加入的边,如果有很这两点之间在最小生成树里的最大边相等的,就说明有次小生成树。
#include <iostream> #include<cstring> #include<cstdio> #include<vector> #include<queue> using namespace std; #define INF 0x3f3f3f3f const int MAX=505; int T,m,n;//m点的数量,n边的数量 int mp[MAX][MAX],Maxlen[MAX][MAX],dis[MAX]; int pre[MAX];//生成树里每个点的父节点 bool vis[MAX]; void init(){ for(int i=1;i<=m;i++) for(int j=1;j<=m;j++) mp[i][j]=(i==j?0:INF); } int Prim(){ int mi,minI,pr; memset(vis,0,sizeof(vis)); for(int i=1;i<=m;i++){dis[i]=mp[1][i];pre[i]=1;} vis[1]=1; int sum=0; for(int i=1;i<m;i++){ mi=INF; for(int j=1;j<=m;j++){ if(!vis[j]&&dis[j]<mi){ minI=j; mi=dis[j]; } } if(mi==INF)return -1; pr=pre[minI]; Maxlen[pr][minI]=Maxlen[minI][pr]=mi; for(int j=1;j<=m;j++){ if(vis[j])Maxlen[minI][j]=Maxlen[j][minI]=max(mi,Maxlen[pr][j]); } vis[minI]=1; sum+=mi; for(int j=1;j<=m;j++){ if(!vis[j]&&dis[j]>mp[minI][j]){ dis[j]=mp[minI][j]; pre[j]=minI; } } } return sum; } bool secondMST(){ for(int i=1;i<=m;i++){ for(int j=1;j<=m;j++){ if(pre[i]==j||pre[j]==i||i==j)continue; if(mp[i][j]==Maxlen[i][j])return 1; } } return 0; } int main() { int a,b,l; scanf("%d",&T); while(T--){ scanf("%d%d",&m,&n); init(); while(n--){ scanf("%d%d%d",&a,&b,&l); if(mp[a][b])mp[a][b]=mp[b][a]=min(mp[a][b],l); else mp[a][b]=mp[b][a]=l; } Prim(); /*for(int i=1;i<=m;i++){ for(int j=1;j<=m;j++){ cout<<i<<" "<<j<<" "<<Maxlen[i][j]<<endl; } }*/ if(secondMST())printf("Yes\n"); else printf("No\n"); } return 0; }
相关文章推荐
- iOS7之后statusbar不能更改
- 源码-PL/SQL从入门到精通-第九章-SQL内置函数-Part 2
- 转: memcached Java客户端spymemcached的一致性Hash算法
- 设置oracle开机自启动
- 小记——linux文件名与链接
- android之switch控件的用法
- Retrofit 2.1 入门
- Java-enum
- Android 如何编写基于编译时注解的项目
- 固定成本、可变成本、沉没成本、机会成本
- Android图片资源优化工具
- reset css 的方法总结!
- volatile关键字解析
- CSDN 博客 排名
- Codeforces #363 Vacations
- 启动redis的步骤
- UOJ 217 奇怪的线段树
- 1044-拦截导弹
- nagios自定义脚本直接执行的结果与nrpe执行的结果不同的问题
- 乌云和漏洞盒子两大白帽子平台突然关闭