题目描述
如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出 orz
。
输入格式
第一行包含两个整数 N,M,表示该图共有 N 个结点和 M 条无向边。
接下来 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
模板题,krske:
CODE
#include<bits/stdc++.h>
using namespace std;
long long sum;
int u,v,n,m,k,jk,ans,num,a[200005][5],f[5005];
void qsort(int i,int j)
{
int mid,l,r;
mid=a[(i+j)/2+1][3];
l=i;
r=j;
while(i<=j)
{
while(a[i][3]<mid)i++;
while(a[j][3]>mid)j--;
if(i<=j)
{
swap(a[i][1],a[j][1]);
swap(a[i][2],a[j][2]);
swap(a[i][3],a[j][3]);
i++,j--;
}
}
if(l<j) qsort(l,j);
if(i<r) qsort(i,r);
}
int find(int x)
{
if(f[x]==x) return x;
else return f[x]=find(f[x]);
}
void krske()
{
for(int i=1;i<=m;i++)
{
u=find(a[i][1]);
v=find(a[i][2]);
if(u==v) continue;
sum+=a[i][3];
f[u]=v; k++;
if(k==n-1) jk=1;
if(jk==1) break;
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) f[i]=i;
for(int i=1;i<=m;i++) scanf("%d%d%d",&a[i][1],&a[i][2],&a[i][3]);
qsort(1,m);krske();
if(jk==1) printf("%lld",sum);
else printf("orz");
return 0;
}