次小生成樹模板(kruskal)
阿新 • • 發佈:2019-01-05
kruskal版的次小生成樹。
struct data { int a,b,w; bool vis;///初始化0 } p[20010]; vector<int>g[110]; int f[110],len[110][110]; const int oo=1e9; bool cmp(data a,data b) { if(a.w!=b.w) return a.w<b.w; if(a.a!=b.a) return a.a<b.a; return a.b<b.b; } int fa(int x)///並查集 { if(x!=f[x]) return f[x]=fa(f[x]); return f[x]; } void kruskal()///求次小生成樹 { sort(p,p+m,cmp); for(int i=0; i<=n; i++) { g[i].clear(); g[i].push_back(i); f[i]=i; } int sum=0,k=0;///最小生成樹權值 for(int i=0; i<m; i++) { if(k==n-1)break; int x1=fa(p[i].a),x2=fa(p[i].b); if(x1!=x2) { k++; p[i].vis=1; sum+=p[i].w; int l=g[x1].size(),ll=g[x2].size(); for(int j=0; j<l; j++) for(int k=0; k<ll; k++) len[g[x1][j]][g[x2][k]]=len[g[x2][k]][g[x1][j]]=p[i].w; f[x1]=x2; int tem[110]; for(int j=0; j<ll; j++) tem[j]=g[x2][j]; for(int j=0; j<l; j++) g[x2].push_back(g[x1][j]); for(int j=0; j<ll; j++) g[x1].push_back(tem[j]); } } int cisum=oo;///次小生成樹權值 for(int i=0; i<m; i++) if(!p[i].vis) cisum=min(cisum,sum+p[i].w-len[p[i].a][p[i].b]); }