POJ 1679 The Unique MST 判断最小生成树是否唯一
来源:互联网 发布:英语四级网络课程 编辑:程序博客网 时间:2024/05/18 13:05
题目链接
http://poj.org/problem?id=1679
题意:
判断最小生成树是否唯一
思路:
首先生成一颗最小生成树,然后枚举每条不在生成树里的边(i,j),将其加入生成树中,此时会成环,再去掉生成树里I到j间最大的边,这样可以得到另一个生成树。因为在最小生成树中,最大的边是所有生成树中最小的。这样替换后如果可以生成一个一样生成树,那么最小生成树就不是唯一的。
#include<cstdio>//最小生成树最大的边,是所有生成树中,最大边最小的。 #include<queue> //同理,第二大的边也是最小的。 #include<iostream>#include<vector>#include<map>#include<cstring>#include<string>#include<set>#include<stack>#include<algorithm>#define cle(a) memset(a,0,sizeof(a))#define inf(a) memset(a,0x3f,sizeof(a))#define ll long long#define Rep(i,a,n) for(int i=a;i<=n;i++)using namespace std;const int INF = ( 2e9 ) + 2;const ll maxn =110;int lowcost[maxn],vis[maxn];int c[maxn][maxn],used[maxn][maxn],pre[maxn],max1[maxn][maxn]; // max1[i][j] 代表i到j间的最大的边 pair<int,int> prim(int n){ int ret=0; for(int i=1;i<=n;i++) { lowcost[i]=c[1][i]; pre[i]=1; } memset(used,0,sizeof(used)); memset(max1,0,sizeof(max1)); memset(vis,0,sizeof(vis)); vis[1]=1; for(int i=2;i<=n;i++) { int mn=INF; int pos=-1; for(int k=2;k<=n;k++) if(!vis[k]&&mn>lowcost[k]) { mn=lowcost[k]; pos=k; } if(mn==INF)return make_pair(0,0); ret+=mn; vis[pos]=1; used[pre[pos]][pos]=used[pos][pre[pos]]=1; for(int k=1;k<=n;k++) { if(vis[k]) max1[k][pos]=max1[pos][k]=max(max1[k][pre[pos]],mn); if(!vis[k]&&c[pos][k]<lowcost[k]) { lowcost[k]=c[pos][k]; pre[k]=pos; } } } return make_pair(1,ret);}int main(){ int t; scanf("%d",&t); while(t--) { int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) c[i][j]=INF+1; for(int i=0;i<m;i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); c[u][v]=w; c[v][u]=w; } pair<int,int> ans=prim(n); if(ans.first==0) printf("Not Unique!\n"); else { int f=INF; for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) { if(!used[i][j]&&c[i][j]!=INF+1) { f=min(f,c[i][j]-max1[i][j]); } } if(f==0) printf("Not Unique!\n"); else printf("%d\n",ans.second); } }}
思路2:
先预处理边,判断是否有权值相等的边,用kruscal算法算出最小生成树,并记录哪些边加入了最小生成树中。试着将加入最小生成树的边,且存在有权值与其相等的边,将其删除,重新构造最小生成树,如果出现相同的,那么说明不唯一。
#include<cstdio>#include<queue>#include<iostream>#include<vector>#include<map>#include<cstring>#include<string>#include<set>#include<stack>#include<algorithm>#define cle(a) memset(a,0,sizeof(a))#define inf(a) memset(a,0x3f,sizeof(a))#define ll long long#define Rep(i,a,n) for(int i=a;i<=n;i++)using namespace std;const int INF = ( 2e9 ) + 2;const ll maxn = 110;int f[maxn],del[maxn*maxn],used[maxn*maxn],equ[maxn*maxn];int first;struct edge{ int u,v,w;};vector<edge> e;bool cmp(edge a,edge b){ return a.w<b.w;}int Find(int x){ return f[x]==x?x:f[x]=Find(f[x]);}int Kruscal(int n){ for(int i=1;i<=n;i++)f[i]=i; int ret=0; for(int i=0;i<e.size();i++) { int u=e[i].u,v=e[i].v,w=e[i].w; if(del[i])continue; int xx=Find(u); int yy=Find(v); if(xx!=yy) { f[xx]=yy; if(first) used[i]=1; ret+=w; } } return ret;}int main(){ int t; scanf("%d",&t); while(t--) { int n,m; e.clear(); scanf("%d%d",&n,&m); for(int i=0;i<m;i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); e.push_back(edge{u,v,w}); } sort(e.begin(),e.end(),cmp); memset(equ,0,sizeof(equ)); memset(used,0,sizeof(used)); memset(del,0,sizeof(del)); for(int i=1;i<e.size();i++) { if(e[i-1].w==e[i].w)equ[i-1]=1,equ[i]=1; } first=1; int w1=Kruscal(n); first=0; int unique=1; for(int i=0;i<e.size();i++) { if(equ[i]&&used[i]) { del[i]=1; int temp=Kruscal(n); del[i]=0; if(temp==w1) { printf("Not Unique!\n"); unique=0; break; } } } if(unique) printf("%d\n",w1); }}
阅读全文
0 0
- poj-1679-The Unique MST-最小生成树是否唯一
- poj 1679 The Unique MST (最小生成树是否唯一)
- POJ 1679 The Unique MST 判断最小生成树是否唯一/次小生成树
- poj 1679 The Unique MST(判断最小生成树是否唯一)
- POJ:1679 The Unique MST(判断最小生成树是否唯一)
- poj 1679 The Unique MST(判断最小生成树是否唯一)
- POJ 1679 The Unique MST (判断最小生成树是否唯一)
- poj-1679 The Unique MST 判断最小生成树是否唯一
- poj 1679 The Unique MST (判断最小生成树是否唯一)
- poj 1679 The Unique MST (判断最小生成树是否唯一)
- POJ 题目1679The Unique MST(判断最小生成树是否是唯一的)
- POJ 1679 The Unique MST(判断最小生成树是否唯一)
- POJ 1679 The Unique MST 判断最小生成树是否唯一
- POJ 1679 The Unique MST( 判断最小生成树是否唯一)
- POJ 1679 The Unique MST(判断最小生成树是否唯一)
- POJ 1679 The Unique MST(判断最小生成树是否唯一)
- poj 1679 The Unique MST 判断最小生成树是否唯一 解题报告
- POJ 1679 The Unique MST 判断最小生成树是否唯一
- 2017年8月10号提高组T2 飞行
- 知识点1:C语言中exit()与return的区别
- 笔记:ORACLE数据库基础学习 第一天
- React 虚拟DOM的理解
- Drawerlayout+ViewPager
- POJ 1679 The Unique MST 判断最小生成树是否唯一
- 二分查找法(递归+循环)
- NoSQL之Redis安装测试
- HDU 6140 Hybrid Crystals
- 多目标优化系列(五)IBEA
- HDU 2488 A Knight's Journey(dfs)
- 斐波那契数列
- TCP与UDP基本区别
- LineIterator中文乱码问题