這道題意思是說給一個連通的無向圖...問其最小產生樹的方案是不是唯一的...所謂唯一就是指滿足最小產生樹的方案只有一種...思路很簡單..先Kruskal找到這個圖的最小產生樹..並記錄邊..然後枚舉刪這些邊的某個..看去掉某邊後得到的最小產生樹的值(其實就是找次小產生樹)..若次小產生樹的值==最小產生樹的值.. 則說明方案不唯一..反之方案唯一..
這裡有個很重要的地方一定要留意...那就是得到的次小產生樹必須要囊括住所有的點...有trick就是兩點間線段的價值為0... 那麼有沒有這個線段..得到的產生樹所需代價不會變..但是就會有可能沒有包括所有的點而不是一個真正的產生樹..即時這個值與最小產生樹的值相等..也不能說最小產生樹是不唯一的...
#include<iostream>#include<algorithm>using namespace std; struct node{ int x,y,w; }line[10005];int t,n,m,i,p,father[105],ans,way[10005],num,temp,k;bool cmp(node a,node b){ return a.w<b.w; }int getfather(int k){ if (father[k]==k) return k; return father[k]=getfather(father[k]);}int main(){ freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); scanf("%d",&t); while (t--) { scanf("%d%d",&n,&m); for (i=1;i<=m;i++) scanf("%d%d%d",&line[i].x,&line[i].y,&line[i].w); for (i=1;i<=n;i++) father[i]=i; ans=0; num=0; sort(line+1,line+1+m,cmp); for (i=1;i<=m;i++) if (getfather(line[i].x)!=getfather(line[i].y)) { ans+=line[i].w; father[father[line[i].y]]=father[line[i].x]; way[++num]=i; } for (p=1;p<=num;p++) { temp=0; k=1; for (i=1;i<=n;i++) father[i]=i; for (i=1;i<=m;i++) if (i!=way[p] && getfather(line[i].x)!=getfather(line[i].y)) { temp+=line[i].w; father[father[line[i].y]]=father[line[i].x]; k++; } if (temp==ans && k==n) break; } if (m==0) printf("0\n"); else if (temp==ans && k==n) printf("Not Unique!\n"); else printf("%d\n",ans); } return 0;}