Poj 1679 The Unique MST (最小生成树唯一性判定)
2013-03-08 22:08
621 查看
2014-5-11更新
本题比较靠谱的解法是用次小生成树解。
具体思想可参考:http://blog.csdn.net/jarily/article/details/8912538
以下分析也转自上面的博客。代码按照自己的风格重写了。
基于 Kruscal 的写法可以参考 http://yzmduncan.iteye.com/blog/1018358
题目大意:
*给出一个连通无向图,判断它的最小生成树是否唯一;
*如果唯一,输出生成树的大小,否则输出"Not Unique!";
*
*算法思想:
*本题可以尝试求与最小生成树权值相等的树是否存在;
*但是更好的思路是直接求次小生成树,如果次小生成树等于最小生成树;
*则说明最小生成树不唯一,否则最小生成树一定是唯一的;
2014-5-4 更新 这题测试数据貌似非常弱。。。当时用下面提到的方法居然水过去了,下面给一组反例:
1
4 5
1 2 2
1 3 2
1 4 2
2 4 101
3 4 101
正好最近准备学次小生成树,学会后换方法……
题目链接:http://poj.org/problem?id=1679
题意:给定的图是否具有唯一的最小生成树。
思路:看到网上的代码都是用次小生成树解的,但其实不用那么麻烦。
利用Prim算法求最小生成树,选择最小边时进行判断:是否有两个或以上的未选择顶点到已选顶点集合的权值相等的,若有则最小生成树不唯一。同时在松弛计算的时候也要
对刚加进的顶点进行权值是否相等的判断。
本题比较靠谱的解法是用次小生成树解。
具体思想可参考:http://blog.csdn.net/jarily/article/details/8912538
以下分析也转自上面的博客。代码按照自己的风格重写了。
基于 Kruscal 的写法可以参考 http://yzmduncan.iteye.com/blog/1018358
题目大意:
*给出一个连通无向图,判断它的最小生成树是否唯一;
*如果唯一,输出生成树的大小,否则输出"Not Unique!";
*
*算法思想:
*本题可以尝试求与最小生成树权值相等的树是否存在;
*但是更好的思路是直接求次小生成树,如果次小生成树等于最小生成树;
*则说明最小生成树不唯一,否则最小生成树一定是唯一的;
#include <cstdio> #include <cstring> #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) const int INF=0x3fffffff; const int N=105; int graph ,dis ; int path ;//从i到j的路径上最大边的权值 int pre ; //辅助数组,记录前驱 bool visit ,used ;//边是否在该MST中 int n,m; int Prim () { int Mst=0,i,j; visit[1]=true; for (i=1; i<=n; ++i) { dis[i]=graph[1][i]; pre[i]=1; } for (i=1;i<n;i++) { int k=-1; for (j=1; j<=n; ++j) if (visit[j]==false) { if (k==-1 || dis[j]<dis[k]) k=j; } used[k][pre[k]]=used[pre[k]][k]=true;//加入MST Mst+=graph[pre[k]][k]; visit[k]=true; for (j=1;j<=n;j++) { if (visit[j] && j!=k) //求从k到j的路径上最大边的权值 path[k][j]=path[j][k]=max(path[j][pre[k]],dis[k]); if (visit[j]==false) if (dis[j]>graph[k][j]) //更新相邻顶点的dis { dis[j]=graph[k][j]; pre[j]=k; } } } return Mst; } void Init () { for (int i=0;i<=n;i++) for (int j=i+1;j<=n;j++) graph[i][j]=graph[j][i]=INF; memset(visit,false,sizeof(visit)); memset(used,false,sizeof(used)); memset(path,0,sizeof(path)); } int main () { int T; scanf("%d",&T); while (T--) { scanf("%d%d",&n,&m); Init(); int u,v,w,i; for (i=1;i<=m;i++) { scanf("%d%d%d",&u,&v,&w); graph[u][v]=graph[v][u]=w; } int Mst=Prim(); int ans=INF; for (i=1;i<=n;i++) for (int j=1;j<=n;j++) if (i!=j && used[i][j]==false) ans=min(ans,Mst+graph[i][j]-path[i][j]); if (ans==Mst) printf("Not Unique!\n"); else printf("%d\n",Mst); } return 0; }
2014-5-4 更新 这题测试数据貌似非常弱。。。当时用下面提到的方法居然水过去了,下面给一组反例:
1
4 5
1 2 2
1 3 2
1 4 2
2 4 101
3 4 101
正好最近准备学次小生成树,学会后换方法……
题目链接:http://poj.org/problem?id=1679
题意:给定的图是否具有唯一的最小生成树。
思路:看到网上的代码都是用次小生成树解的,但其实不用那么麻烦。
利用Prim算法求最小生成树,选择最小边时进行判断:是否有两个或以上的未选择顶点到已选顶点集合的权值相等的,若有则最小生成树不唯一。同时在松弛计算的时候也要
对刚加进的顶点进行权值是否相等的判断。
#include <cstdio> #include <cstring> const int INF=0x7fffffff; int map[105][105],dis[105]; int m,n; bool visit[105]; int Prim () { int i,j,k; int temp,ans=0; for (i=1;i<=n;i++) dis[i]=map[1][i]; visit[1]=true; for (i=1;i<n;i++) { for (temp=INF,j=1;j<=n;j++) if (dis[j]<temp && visit[j]==false) temp=dis[k=j]; ans+=temp; visit[k]=true; for (j=1;j<=n;j++) if (visit[j]==false && dis[j]==temp) return -1; for (j=1;j<=n;j++) if (visit[j]==false) if (dis[j]>map[k][j]) dis[j]=map[k][j]; else if (dis[j]==map[k][j] && dis[j]!=INF) return -1; } return ans; } void init () { int i; for (i=1;i<=n;i++) for (int j=1;j<=n;j++) map[i][j]=INF; for (i=1;i<=n;i++) map[i][i]=0; memset(visit,false,sizeof(visit)); } int main () { int T; scanf("%d",&T); while (T--) { int x,y,w; scanf("%d%d",&n,&m); init (); for (int i=0;i<m;i++) { scanf("%d%d%d",&x,&y,&w); map[x][y]=w; map[y][x]=w; } int ans=Prim(); if (ans == -1) printf("Not Unique!\n"); else printf("%d\n",ans); } return 0; }
相关文章推荐
- (kruscal12.3.4)POJ 1679 The Unique MST(判断最小生成树的唯一性||次小生成树)
- POJ 1679-The Unique MST( 判断最小生成树的唯一性)
- POJ1679 The Unique MST(Kruskal)(最小生成树的唯一性)
- poj 1679 The Unique MST【次小生成树】【判断最小生成树的唯一性】
- 【POJ1679】The Unique MST-次小生成树(判断最小生成树唯一性)
- POJ 1679 The Unique MST(判断最小生成树是否唯一)
- POJ 1679-The Unique MST(最小生成树是否唯一)
- POJ 1679 The Unique MST 最小代价生成树 次小代价生成树
- POJ 1679 The Unique MST(最小生成树--prime||次小生成树)
- Poj 1679 The Unique MST 判断最小生成树是否唯一
- POJ1679 The Unique MST(判断最小生成树是否唯一)
- poj-1679 The Unique MST 判断最小生成树是否唯一
- poj 1679 The Unique MST (最小生成树)
- poj1679.The Unique MST(最小生成树是否唯一)
- POJ 1679 The Unique MST(判断最小生成树是否唯一)
- POJ 1679 The Unique MST(kuangbin带你飞 专题六:最小生成树)
- poj 1679 The Unique MST (最小生成树)
- POJ 1679 The Unique MST(判断最小生成树是否唯一)
- PKU1679(The Unique MST)判断最小生成树的唯一性-次小生成树
- poj-1679-The Unique MST-最小生成树是否唯一