题意:
给定n个点m条无向带权边的图
问:是否最小生成树唯一
是则输出最小生成树的权值
思路:
求出次小生成树,判断权值是否于最小生成树相同即可。
dp[u][v] 表示在最小生成树下 [u,v] 路径中最大的边权值
每次BFS求出u点距离其他点的 路径上的最大边权值。
#include<iostream> #include<algorithm> #include<stdio.h> #include<vector> #include<queue> #include<string.h> using namespace std; #define N 105 #define M 100005 #define inf 1000000 struct Edge{ int from, to, dis, yes; bool operator<(const Edge&a)const{ return a.dis>dis; } }edge[M]; vector<int>G[N]; int f[N]; int find(int x){return x==f[x] ? x : f[x] = find(f[x]);} bool Union(int x, int y){ int fx = find(x), fy = find(y); if(fx == fy)return true; if(fx<fy)f[fx] = fy; else f[fy] = fx; return false; } int n, m, dp[N][N], dis[N][N], num; int Kru(){ int ans = 0;num = 0; sort(edge, edge+m); for(int i = 0; i < m; i++){ int u = edge[i].from, v = edge[i].to; if(Union(u,v))continue; num++; ans += edge[i].dis; G[u].push_back(v), G[v].push_back(u); edge[i].yes = 1; dis[u][v] = dis[v][u] = edge[i].dis; } if(num == n-1)return ans; return -inf; } struct node{ int maxdis, to, fa; node(int a=0,int c=0,int d=0):maxdis(a),to(c),fa(d){} }; void BFS(int x){ queue<node>q; q.push(node(0, x,-1)); while(!q.empty()){ node u = q.front(); q.pop(); for(int i = 0; i < G[u.to].size(); i++){ int v = G[u.to][i]; if(v == u.fa)continue; int nowmax = max(dis[u.to][v], u.maxdis); dp[x][v] = dp[v][x] = max(dp[x][v], nowmax); q.push(node(nowmax, v, u.to)); } } } void init(){ memset(dp, 0, sizeof(dp)); for(int i = 1; i <= n; i++) { G[i].clear(), f[i] = i; for(int j = 1; j <= n; j++)dis[i][j] = inf; dis[i][i] = 0; } } int main(){ int T, u, v, i, j;scanf("%d",&T); while(T--){ scanf("%d %d",&n,&m); init(); for(i = 0; i < m; i++) { scanf("%d%d%d",&edge[i].from, &edge[i].to, &edge[i].dis); u = edge[i].from, v = edge[i].to; edge[i].yes = false; } int mindis = Kru(); for(i = 1; i <= n; i++) BFS(i); int ans = inf; for(i = 0; i < m; i++)if(!edge[i].yes) { int u = edge[i].from, v = edge[i].to; ans = min(ans, mindis + edge[i].dis - dp[u][v]); } if(ans == mindis)puts("Not Unique!"); else printf("%d\n", mindis); } return 0; } /* 99 3 3 1 2 2 2 3 3 3 1 3 3 3 1 2 3 2 3 2 3 1 3 3 2 1 2 2 2 3 2 */