题目描述
如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出orz
输入输出格式
输入格式:第一行包含两个整数N、M,表示该图共有N个结点和M条无向边。(N<=5000,M<=200000)
接下来M行每行包含三个整数Xi、Yi、Zi,表示有一条长度为Zi的无向边连接结点Xi、Yi
输出格式:
输出包含一个数,即最小生成树的各边的长度之和;如果该图不连通则输出orz
思路:套板子,需要注意的是若图不连通则需判断加进来的点数是否等于n-1,见代码
#include<cstdio>
#include<algorithm>
using namespace std;
int par[5010];
int rank[5010];
int n,m;
int cnt=0;
struct edge
{
int u,v,cost;
} ;
edge es[200010];
bool cmp(const edge& e1,const edge &e2)
{
return e1.cost<e2.cost;
}
void init()
{
for(int i=1;i<=n;i++)
{
par[i]=i;
rank[i]=0;
}
}
int find(int x)
{
if(par[x]==x)
return x;
else
return par[x]=find(par[x]);
}
void unite(int x,int y)
{
if(find(x)==find(y))
return ;
else
{
x=find(x);
y=find(y);
if(rank[x]<rank[y])
{
par[x]=y;
}
else
{
par[y]=x;
if(rank[x]==rank[y])
rank[x]++;
}
}
}
bool same(int x,int y)
{
if(find(x)==find(y))
return true;
else
return false;
}
int kru()
{
sort(es,es+m,cmp);
init();
int res=0;
for(int i=0;i<m;i++)
{
edge e=es[i];
if(!same(e.u,e.v))
{
unite(e.u,e.v);
res+=e.cost;
cnt++;
}
}
if(cnt==n-1)
return res;
else
return 0;
}
int main()
{
int x1,y1,z1;
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&x1,&y1,&z1);
es[i].u=x1;
es[i].v=y1;
es[i].cost=z1;
}
printf("%d",kru());
return 0;
}