POJ1679
来源:互联网 发布:国动网络通信集团网站 编辑:程序博客网 时间:2024/05/17 03:03
Problem: The Unique MST
Description: 问最小生成树是否唯一。如果唯一求出最小生成树的值。
Solution: Kruskal或者Prim. 如果用Kruskal算法的话,我们在并查集枚举边枚举到当前边的时候我们向后比较是否存在同当前边距离相同同时父节点也相同的边,如果有,那么最小生成树连边的话就有两种选择,这个时候就不是唯一的了;如果用Prim算法,那么我们就求次小生成树。看次小生成树和最小生成树是否相同。如果相同就不是唯一的了。
Code(C++):
kruskal:
#include <stdio.h>#include <string.h>#include <stdlib.h>const int M=105;const int E=M*(M-1)/2;typedef struct tagEdge{ int from,to; int value;}Edge;Edge edges[E];int n,m;int p[M];int cmp(const void *a,const void *b){ Edge *A=(Edge *)a; Edge *B=(Edge *)b; return A->value-B->value;}int find(int x){ return x==p[x]? x:p[x]=find(p[x]);}int kruskal(){ bool flag=true; int sum=0; for(int i=0;i<m;i++){ int px=find(edges[i].from); int py=find(edges[i].to); if(px==py) continue; for(int j=i+1;j<m;j++){ if(edges[i].value!=edges[j].value) break; int tmp_px=find(edges[j].from); int tmp_py=find(edges[j].to); if((tmp_px==px&&tmp_py==py)||(tmp_px==py&&tmp_py==px)){ flag=false; break; } } if(!flag) break; p[px]=py; sum+=edges[i].value; } if(!flag) return -1; return sum;}int main(){ int N; for(scanf("%d",&N);N--;){ scanf("%d%d",&n,&m); for(int i=0;i<m;i++) scanf("%d%d%d",&edges[i].from,&edges[i].to,&edges[i].value); qsort(edges,m,sizeof(edges[0]),cmp); for(int i=0;i<=n;i++) p[i]=i; int ans=kruskal(); if(ans==-1) puts("Not Unique!"); else printf("%d\n",ans); } return 0;}
prim:
#include <stdio.h>#include <string.h>#define MAX(a,b) ((a)>(b)? (a):(b))#define MIN(a,b) ((a)<(b)? (a):(b))const int M=105;const int INF=0x3f3f3f3f;int map[M][M];int n,m;int dis[M];bool used[M];int dp[M][M];int pre[M];int stack[M];int prim(int src){ int top=0; int ans=0; for(int i=0;i<M;i++){ for(int j=0;j<M;j++) dp[i][j]=0; pre[i]=src; used[i]=false; dis[i]=map[src][i]; } dis[src]=0; used[src]=true; for(int i=1;i<n;i++){ int tmp=INF,k=src; for(int j=1;j<=n;j++) if(!used[j]&&dis[j]<tmp) tmp=dis[j],k=j; if(k==src) break; ans+=tmp; used[k]=true; for(int j=1;j<top;j++) dp[k][stack[j]]=dp[stack[j]][k]=MAX(tmp,dp[pre[k]][stack[j]]); stack[top++]=k; for(int j=1;j<=n;j++) if(!used[j]&&dis[j]>map[k][j]) pre[j]=k, dis[j]=map[k][j]; } return ans;}int main(){ int N; for(scanf("%d",&N);N--;){ scanf("%d%d",&n,&m); for(int i=1;i<n;i++) for(int j=i+1;j<=n;j++) map[i][j]=map[j][i]=INF; for(int i=0;i<m;i++){ int x,y,c; scanf("%d%d%d",&x,&y,&c); map[x][y]=map[y][x]=c; } int ans=prim(1); int flag=INF; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(i!=j&&i!=pre[j]&&j!=pre[i]) flag=MIN(flag,map[i][j]-dp[i][j]); if(!flag) puts("Not Unique!"); else printf("%d\n",ans); } return 0;}
0 0
- poj1679
- poj1679
- poj1679
- poj1679
- poj1679
- POJ1679
- POJ1679
- POJ1679
- POJ1679:The Unique MST
- POJ1679 The Unique MST
- poj1679----最小生成树
- poj1679 - The Unique MST
- POJ1679 The Unique MST
- poj1679 The Unique MST
- poj1679 The Unique MST
- POJ1679------The Unique MST
- POJ1679-The Unique MST
- poj1679 The Unique MST
- numpy 常用api(四)
- ExtJs TabPanel右键功能插件Ext.ux.TabCloseMenu
- 页面滚动条 刷新后 保持在原来的位置
- c++复习要点总结之七——运算符重载
- 你不懂带人你就自己干到死——摘录
- POJ1679
- Java集合类框架的实践经验
- Learning from data: Bias-Variance Tradeoff
- mybatis的学习
- U-Boot的编译过程分析
- android之常用知识点(一)
- WPF学习——依赖项属性(2)
- 代码总结
- Java web.xml配置 servlet