最小生成树1
Time Limit:10000MS Memory Limit:234567K
Total Submit:108 Accepted:54
Case Time Limit:1000MS
Description
给定一个N个节点M条边的带权无向图,节点从1到N开始编号,求最小生成树
Input
第一行两个数N,M,表示点数和边数
接下来M行每行三个数u,v,w,表示u,v之间有一条权为w的边
可能有重边,但是没有自环
Output
如果最小生成树存在,输出树上所有边的权值和
如果不存在,输出“Keng Die!”
Sample Input
4 5
1 2 1
2 3 2
3 4 3
4 1 4
1 3 5
Sample Output
6
Hint
1<=N<=200000
N-1<=M<=500000
0<=每条边的权值<=5000
Source
先用 kruscal:
#include <cstdio> #include <cstdlib> using namespace std; const int maxn=200005,maxm=500005; int fath[maxn],x[maxm],y[maxm],z[maxm],N,M; inline void _getnum(int &xx) { char tt=getchar(); while(tt<'0'||tt>'9')tt=getchar(); for(xx=0;tt>='0'&&tt<='9';tt=getchar())xx=xx*10+(tt-'0'); } void _qst(int l,int r) { int i,j,m,t; i=l;j=r; m=z[(i+j)>>1]; while(i<=j) { while(z[i]<m)i++; while(z[j]>m)j--; if(i<=j) { t=x[i];x[i]=x[j];x[j]=t; t=y[i];y[i]=y[j];y[j]=t; t=z[i];z[i]=z[j];z[j]=t; i++;j--; } } if(i<r)_qst(i,r); if(l<j)_qst(l,j); } int _getfath(int i) { if(fath[i]!=i)fath[i]=_getfath(fath[i]); return fath[i]; } int main() { int i,j,ans=0,X,Y; _getnum(N);_getnum(M); for(i=1;i<=M;i++)_getnum(x[i]),_getnum(y[i]),_getnum(z[i]); _qst(1,M); for(i=1;i<=N;i++)fath[i]=i; for(i=j=1;i<=M&&j<N;i++) { X=_getfath(x[i]); Y=_getfath(y[i]); if(X!=Y)fath[X]=Y,j++,ans+=z[i]; } if(j==N)printf("%d",ans); else printf("Keng Die!"); return 0; }然后是prim:
#include <cstdio> #include <cstdlib> using namespace std; const int maxn=200005,maxm=1000005; int N,M,dis[maxn],H[maxn],pH[maxn],tot; int y[maxm],z[maxm],next[maxm],last[maxn]; inline void _getnum(int &xx) { char tt=getchar(); while(tt<'0'||tt>'9')tt=getchar(); for(xx=0;tt>='0'&&tt<='9';tt=getchar())xx=xx*10+(tt-'0'); } void _shift_up(int i) { int j=i>>1,t=H[i]; while(j>=1) { if(dis[H[j]]>dis[t]) { H[i]=H[j]; pH[H[i]]=i; i=j;j=i>>1; } else break; } H[i]=t;pH[H[i]]=i; } void _shift_down(int i) { int j=i<<1,t=H[i]; while(j<tot) { if(j+1<tot&&dis[H[j]]>dis[H[j+1]])j++; if(dis[t]>dis[H[j]]) { H[i]=H[j]; pH[H[i]]=i; i=j;j=i<<1; } else break; } H[i]=t;pH[H[i]]=i; } void _prim() { int i,j,k,t,ans=0; for(i=1;i<=N;i++) { H[i]=pH[i]=i; dis[i]=999999999; } dis[1]=0;tot=N+1; for(i=1;i<=N;i++) { k=H[1];H[1]=H[--tot];pH[H[1]]=1;pH[k]=0; _shift_down(1); if(dis[k]==999999999){printf("Keng Die!");return;} ans+=dis[k]; for(j=last[k];j>0;j=next[j]) if(pH[y[j]]!=0&&dis[y[j]]>z[j]) { dis[y[j]]=z[j]; _shift_up(pH[y[j]]); } } printf("%d",ans); } int main() { int i,j,k,t; _getnum(N);_getnum(M); for(i=j=1;i<=M;i++) { _getnum(k);_getnum(t);_getnum(z[j]); y[j]=t;next[j]=last[k];last[k]=j++; y[j]=k;z[j]=z[j-1];next[j]=last[t];last[t]=j++; } _prim(); return 0; }