UVA 10600 ACM Contest and Blackout ( 水題次小生成樹 )
UVa Online Judge
算出最小生成樹上每對最小瓶頸路徑就能 O( n * n ) 解決。
碎念:find() 函數忘了寫 return這個字= =
#include <bits/stdc++.h> using namespace std; const int MAXN = 100 + 2; // 1 idx const int MAXC = 300 + 2; const int MAXM = MAXN * MAXN / 2; const int INF = 1e9; struct UnionFind{ int fa[MAXN]; void init(int n){ for(int i = 0; i <= n; ++i) fa[i] = i; } int find(int x){ return fa[x] == x ? x : fa[x] = find( fa[x] ); } bool unite(int a, int b){ int x = find( a ), y = find( b ); if( x == y ) return false; fa[x] = y; return true; } } uf; struct Edge{ int u, v, w; Edge(){} Edge(int _u, int _v, int _w): u(_u), v(_v), w(_w){} bool operator < (const Edge &oth) const{ return w < oth.w; } } es[MAXM]; int n, m; int wei[MAXN][MAXN]; vector<Edge> G[MAXN]; struct Kruskal{ int vis[MAXN], maxcost[MAXN][MAXN]; vector<int> vis_node; void init(){ uf.init( n ); sort( es, es + m ); memset( vis, 0, sizeof(vis) ); memset( maxcost, 0, sizeof(maxcost) ); for(int i = 0; i <= n; ++i) G[i].clear(); vis_node.clear(); } void findBottleneckPath(int u, int fa){ for(int x: vis_node) maxcost[ x ][ u ] = maxcost[ u ][ x ] = max( maxcost[ x ][ fa ], wei[ fa ][ u ] ); vis_node.push_back( u ); for(int i = 0; i < G[u].size(); ++i){ int v = G[u][i].v; if( v == fa ) continue; findBottleneckPath( v, u ); } } void solve(){ int picked = 0, ans1 = 0; for(int i = 0; i < m; ++i){ if( uf.unite( es[i].u, es[i].v ) ){ vis[ i ] = 1; G[ es[i].u ].push_back( Edge( es[i].u, es[i].v, es[i].w ) ); G[ es[i].v ].push_back( Edge( es[i].v, es[i].u, es[i].w ) ); ans1 += es[i].w; if( ++picked == n - 1 ) break; } } assert( picked == n - 1 ); findBottleneckPath( 1, -1 ); int mindiff = INF; for(int i = 0; i < m; ++i) if( !vis[ i ] ) mindiff = min( mindiff, es[i].w - maxcost[ es[i].u ][ es[i].v ] ); int ans2 = ans1 + mindiff; printf("%d %d\n", ans1, ans2); } } mst; void solve(){ mst.init(); mst.solve(); } int main(){ int T; scanf("%d", &T); while( T-- ){ scanf("%d%d", &n, &m); for(int i = 0; i < m; ++i){ int u, v, w; scanf("%d%d%d", &u, &v, &w); es[ i ] = Edge( u, v, w ); wei[ u ][ v ] = wei[ v ][ u ] = w; } solve(); } return 0; }