判断MST时候唯一,用prime算法,复杂度O(n^2)
#define N 105 int n,m; int dis[N],g[N][N]; bool vis[N]; int mx[N][N];//记录路径i-j最大的边值 int pre[N];//记录最小生成树路径 bool intree[N][N];//判断哪些边属于MST int prime(int s){ int i,j; for(i=1;i<=n;i++){ dis[i] = g[s][i]; vis[i] = 0; pre[i] = 1; } dis[s] = 0; vis[s] = 1; int ans = 0; for(i=1;i<n;i++){ int minm = MAX; int tmp; for(j=1;j<=n;j++){ if(!vis[j] && dis[j]<minm){ minm = dis[j]; tmp = j; } } if(minm==MAX)return -1;//不连通 vis[tmp] = 1; intree[pre[tmp]][tmp] = intree[tmp][pre[tmp]] = true; ans += minm; for(j=1;j<=n;j++){ if(vis[j]) mx[j][tmp] = max(mx[j][pre[tmp]], g[pre[tmp]][tmp]); } for(j=1;j<=n;j++){ if(!vis[j] && dis[j]>g[tmp][j]){ dis[j] = g[tmp][j]; pre[j] = tmp; } } } return ans; } void init(){ int i,j; for(i=1;i<=n;i++){ for(j=i+1;j<=n;j++){ g[i][j] = g[j][i] = MAX; mx[i][j] = mx[j][i] = 0; intree[i][j] = intree[j][i] = 0; } } } int main(){ int t; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); init(); int i,j; while(m--){ int a,b,c; scanf("%d%d%d",&a,&b,&c); g[a][b] = g[b][a] = c; } int ans = prime(1); if(ans<0){ printf("0\n"); continue; } bool ok = 0; for(i=1;i<=n;i++){ for(j=i+1;j<=n;j++){ if(intree[i][j] || g[i][j]==MAX)continue;//排除已经属于MST和i,j没有边的情况 int res = ans - mx[i][j] + g[i][j];//用不属于MST的边替代i,j路径最大的边,如果只一样证明不唯一 if(res==ans){ ok = 1; break; } } if(ok)break; } if(ok)puts("Not Unique!"); else printf("%d\n",ans); } return 0; }