poj 1679 The Unique MST ( 次小生成树 )
(n^3) -- kruskal 枚举边
#include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> #define N 110 #define inf 99999999 using namespace std; struct node { int x,y,len; }root[N*N]; int n,m,num[N]; int top,stack[N]; int find(int x) { if(num[x] == x) return x; return num[x] = find(num[x]); } int cmp(node a,node b) { return a.len<b.len; } int kruskal(int pos) { if(pos==-1) top=0; for(int i=1;i<=n;i++) num[i]=i; int ans=0,cnt=0; for(int i=0;i<m;i++) { if(i==pos) continue ; int tx=find(root[i].x); int ty=find(root[i].y); if(tx!=ty) { num[ty]=tx;cnt++; ans+=root[i].len; if(pos==-1) stack[top++]=i; if(cnt==n-1) break; } } if(cnt!=n-1) return -1; return ans; } int main() { int cs;cin>>cs; while(cs--) { memset(root,0,sizeof(root)); memset(stack,0,sizeof(stack)); scanf("%d%d",&n,&m); for(int i=0;i<m;i++) scanf("%d%d%d",&root[i].x,&root[i].y,&root[i].len); sort(root,root+n,cmp); int minf=kruskal(-1); int tmin=inf,t; for(int i=0;i<top;i++) { t=kruskal(stack[i]); if(t!=-1&&t<tmin) tmin=t; } if(minf==tmin) puts("Not Unique!"); else printf("%d\n",minf); } return 0; }
(n^2) prim
理解不是太清晰,先放个模版吧
#include<cstdio> #include<cstring> #include<cstdlib> const int inf = 0x3f3f3f3f; const int N = 105; bool Tlink[N][N], vis[N]; int w[N][N], lowc[N], pre[N], max[N][N]; int n, m; int Max( int a, int b) { return a > b ? a : b; } int prim() { int i, j, p, k; int minc, res = 0; memset( vis, false, sizeof vis); memset( pre, 0, sizeof pre); memset( max, 0, sizeof max); vis[1] = 1;pre[1] = 1; for( i = 2; i <= n; i ++) { lowc[i] = w[1][i]; pre[i] = 1;} for( i = 2; i <= n; i ++) { minc = inf; p = -1; for( j = 1; j <= n; j ++) if( !vis[j] && lowc[j] < minc) minc = lowc[j], p = j; vis[p] = true; res += minc; max[ pre[p] ][p] = minc; Tlink[ pre[p] ][p] = true; Tlink[p][ pre[p] ] = true; for( k = 1; k <= n; k ++) max[k][p] = Max( max[ pre[p] ][p], max[k][p]); for( j = 1; j <= n; j ++) if( !vis[j] && lowc[j] > w[p][j]) lowc[j] = w[p][j],pre[j] = p; } return res; } int main() { int T;scanf( "%d", &T); while( T --) { int s, e, t, Ans, ans; scanf( "%d%d", &n, &m); for( int i = 1; i <= n; i ++) for( int j = 1; j <= n; j ++) w[i][j] = inf; memset( Tlink, false, sizeof Tlink); for( int i = 1; i <= m; i ++) { scanf( "%d%d%d", &s, &e, &t); w[s][e] = w[e][s] = t; } bool ok = true; Ans = prim(); for( int i = 1; i <= n; i ++) { for( int j = 1; j <= n; j ++) { if( w[i][j] == inf || Tlink[i][j]) continue; ans = Ans + w[i][j] - max[i][j]; if( Ans == ans) { ok = false; break; } } if( ! ok ) break; } if( ok) printf( "%d\n", Ans); else printf( "Not Unique!\n"); } return 0; }
Just a little, maybe change the world