【POJ1679】The Unique MST-次小生成树(判断最小生成树唯一性)

来源:互联网 发布:淘宝信誉等级在哪里看 编辑:程序博客网 时间:2024/06/10 00:28

测试地址:The Unique MST

题目大意:给一个连通的无向图,要求判断该图的最小生成树是不是唯一的,如果对于该图的所有除了最小生成树之外的生成树,花费都严格大于最小生成树的花费,则该图的最小生成树是唯一的。如果唯一,输出最小花费,否则输出“Not Unique!”。

做法:用次小生成树的做法来做这一题,如果次小生成树的花费和最小生成树相等,那么最小生成树就不唯一。求次小生成树的方法网上有讲,这里不再赘述。

以下是本人代码:

#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>#define inf 1000000007using namespace std;int T,n,m,len[110][110],first[110],last[110],fa[110],mst,smst;struct edge {int a,b,d,next;} e[50010];bool used[110];bool cmp(edge a,edge b){  return a.d<b.d;}int find(int x){  int r=x,i=x,j;  while(r!=fa[r]) r=fa[r];  while(i!=r) j=fa[i],fa[i]=r,i=j;  return r;}void merge(int a,int b){  int fx=find(a),fy=find(b);  fa[fy]=fx;}void kruskal(){  mst=0;  sort(e+1,e+m+1,cmp);  memset(first,0,sizeof(first));  memset(used,0,sizeof(used));  for(int i=1;i<=n;i++)  {    fa[i]=i;first[i]=last[i]=m+i;e[m+i].a=e[m+i].b=i;e[m+i].next=0;  }    for(int i=1;i<=m;i++)  {    if (find(e[i].a)!=find(e[i].b)){  for(int j=first[fa[e[i].a]];j;j=e[j].next)    for(int k=first[fa[e[i].b]];k;k=e[k].next){  len[e[j].b][e[k].b]=len[e[k].b][e[j].b]=e[i].d;}  e[last[fa[e[i].a]]].next=first[fa[e[i].b]];  last[fa[e[i].a]]=last[fa[e[i].b]];  merge(e[i].a,e[i].b);  mst+=e[i].d;  used[i]=1;}  }}int main(){  scanf("%d",&T);  while(T--)  {    scanf("%d%d",&n,&m);memset(first,0,sizeof(first));for(int i=1;i<=m;i++)  scanf("%d%d%d",&e[i].a,&e[i].b,&e[i].d);kruskal();smst=inf;for(int i=1;i<=m;i++)  if (!used[i]) smst=min(smst,mst-len[e[i].a][e[i].b]+e[i].d);if (smst==mst) printf("Not Unique!\n");else printf("%d\n",mst);  }    return 0;}


0 0
原创粉丝点击