【luogu 3366】【模板】最小生成樹
阿新 • • 發佈:2017-10-07
接下來 class deep 兩個 生成樹 生成 last 模板 blog
題目描述
如題,給出一個無向圖,求出最小生成樹,如果該圖不連通,則輸出orz
輸入輸出格式
輸入格式:
第一行包含兩個整數N、M,表示該圖共有N個結點和M條無向邊。(N<=5000,M<=200000)
接下來M行每行包含三個整數Xi、Yi、Zi,表示有一條長度為Zi的無向邊連接結點Xi、Yi
輸出格式:
輸出包含一個數,即最小生成樹的各邊的長度之和;如果該圖不連通則輸出orz
輸入輸出樣例
輸入樣例#1:4 5 1 2 2 1 3 2 1 4 3 2 3 4 3 4 3輸出樣例#1:
7
說明
時空限制:1000ms,128M
數據規模:
對於20%的數據:N<=5,M<=20
對於40%的數據:N<=50,M<=2500
對於70%的數據:N<=500,M<=10000
對於100%的數據:N<=5000,M<=200000
樣例解釋:
所以最小生成樹的總邊權為2+2+3=7
kruskal:
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #define maxn 5003 6 #define maxm 200005 7 using namespace std; 8int read(){ 9 int x=0,f=1;char ch=getchar(); 10 while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} 11 while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} 12 return x*f; 13 } 14 int fa[maxn],deep[maxn]; 15 int n,m,tot=0,ans=0; 16 struct node{int u,v,w;}e[maxm];17 bool cmp(node a,node b){return a.w<b.w;} 18 int find(int x){ 19 if(fa[x]==x) return x; 20 else return fa[x]=find(fa[x]); 21 } 22 void unite(int x,int y){ 23 x=find(x),y=find(y); 24 if(x==y) return ; 25 if(deep[x]<deep[y]) fa[x]=y; 26 else{ 27 fa[y]=x; 28 if(deep[x]==deep[y]) deep[x]++; 29 } 30 } 31 bool same(int x,int y){ 32 return find(x)==find(y); 33 } 34 int main(){ 35 n=read(),m=read(); 36 for(int i=1;i<=n;i++) fa[i]=i,deep[i]=0; 37 for(int i=1;i<=m;i++) 38 e[i].u=read(),e[i].v=read(),e[i].w=read(); 39 sort(e+1,e+m+1,cmp); 40 for(int i=1;i<=m;i++){ 41 if(same(e[i].u,e[i].v)) continue; 42 else{ 43 unite(e[i].u,e[i].v); 44 ans+=e[i].w; 45 tot++; 46 } 47 } 48 if(tot<n-1) printf("orz"); 49 else printf("%d",ans); 50 return 0; 51 }
prim:
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #define maxn 5005 6 #define maxm 200005 7 #define INF 0x3f3f3f3f 8 using namespace std; 9 int read(){ 10 int x=0,f=1;char ch=getchar(); 11 while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} 12 while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} 13 return x*f; 14 } 15 int n,m,dis[maxn],last[maxn],cnt,ans; 16 bool vis[maxn]; 17 struct node{int to,next,cost;}e[2*maxm]; 18 void add(int u,int v,int w){ 19 e[++cnt].to=v;e[cnt].next=last[u];last[u]=cnt;e[cnt].cost=w; 20 } 21 void prim(){ 22 for(int i=1;i<=n;i++) dis[i]=INF; 23 dis[1]=0; 24 for(int j=1;j<=n;j++){ 25 int u=-1,minn=INF; 26 for(int i=1;i<=n;i++){ 27 if(dis[i]<minn&&!vis[i]){ 28 u=i; 29 minn=dis[i]; 30 } 31 } 32 if(u==-1){ 33 ans=-1; 34 return ; 35 } 36 vis[u]=1; 37 ans+=dis[u]; 38 for(int i=last[u];i;i=e[i].next){ 39 int v=e[i].to; 40 if(!vis[v]&&dis[v]>e[i].cost) dis[v]=e[i].cost; 41 } 42 } 43 } 44 int main(){ 45 n=read(),m=read(); 46 for(int i=1;i<=m;i++){ 47 int u=read(),v=read(),w=read(); 48 add(u,v,w); 49 add(v,u,w); 50 } 51 prim(); 52 if(ans==-1) printf("orz\n"); 53 printf("%d\n",ans); 54 return 0; 55 }
【luogu 3366】【模板】最小生成樹