首页 > 代码库 > The Unique MST(poj 1679)
The Unique MST(poj 1679)
题意:求次小生成树,若权值和与最小生成树相等,输出"Not Unique!" ;否则,输出mst
/* 次小生成树 首先明白一点,次小生成树是由最小生成树改变一条边得来的,然后我们就可以先求出最小生成树, 然后枚举没在最小生成树中的边(x、y、z),用这条边来替换树中x、y之间的一条边,很显然,替换 时应该替换x、y中的最长边,所以可以预处理出树中x、y之间的最长边。*/#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#define N 110#define INF 1000000000using namespace std;int head[N],g[N][N],fa[N],vis[N*N],n,m,cnt,mst;struct node{ int x,y,z;};node ee[N*N];struct Node{ int v,pre,t;};Node e[N*2];bool cmp(const node&s1,const node&s2){ return s1.z<s2.z;}int find(int x){ if(fa[x]==x)return x; return fa[x]=find(fa[x]);}void add(int x,int y,int z){ ++cnt; e[cnt].v=y; e[cnt].t=z; e[cnt].pre=head[x]; head[x]=cnt;}void dfs(int s,int now,int from,int mmx){ g[s][now]=mmx; for(int i=head[now];i;i=e[i].pre) if(e[i].v!=from) dfs(s,e[i].v,now,max(mmx,e[i].t));}void work(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)fa[i]=i; for(int i=1;i<=m;i++) { int x,y,z; scanf("%d%d%d",&ee[i].x,&ee[i].y,&ee[i].z); } sort(ee+1,ee+m+1,cmp); for(int i=1;i<=m;i++) { int a=find(ee[i].x),b=find(ee[i].y); if(a!=b) { fa[a]=b;mst+=ee[i].z;vis[i]=1; add(ee[i].x,ee[i].y,ee[i].z); add(ee[i].y,ee[i].x,ee[i].z); } } for(int i=1;i<=n;i++) dfs(i,i,-1,0); int ans=INF; for(int i=1;i<=m;i++) if(!vis[i]) ans=min(ans,mst-ee[i].z+g[ee[i].x][ee[i].y]); if(ans==mst)printf("Not Unique!\n"); else printf("%d\n",mst);}int main(){ int T;scanf("%d",&T); while(T--) { memset(g,0,sizeof(g)); memset(fa,0,sizeof(fa)); memset(head,0,sizeof(head)); memset(vis,0,sizeof(vis)); mst=cnt=0; work(); } return 0;}
The Unique MST(poj 1679)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。