图结构练习——最小生成树
题目描述
有n个城市,其中有些城市之间可以修建公路,修建不同的公路费用是不同的。现在我们想知道,最少花多少钱修公路可以将所有的城市连在一起,使在任意一城市出发,可以到达其他任意的城市。
输入
输入包含多组数据,格式如下。
第一行包括两个整数n m,代表城市个数和可以修建的公路个数。(n <= 100, m <=1000)
剩下m行每行3个正整数a b c,代表城市a 和城市b之间可以修建一条公路,代价为c。
输出
每组输出占一行,仅输出最小花费。
示例输入
3 2 1 2 1 1 3 1 1 0
示例输出
2 0
#include<bits/stdc++.h>
using namespace std;
struct node
{
int u,v,w;
} pp[100050];
int pre[100050];
int t,i,n,m;
//结构体一级排序
int cmp(node p1,node p2)
{
return p1.w<p2.w;
}
//并查集详解
int find(int x)
{
int r=x,k,j;
while(r!=pre[r])
{
r=pre[r];
}
k=x;
while(k!=r)
{
j=pre[k];
pre[k]=r;
k=j;
}
// int i=x;
// while(pre[i]!=r)
// {
// j=pre[i];
// pre[i]=r;
// i=j;
// }
return r;
}
void mix(int x,int y)
{
int fx=find(x);
int fy=find(y);
if(fx!=fy)
{
pre[fx]=fy;
}
}
void kruskal()
{
int i;
int sum=0,num=0;
for(i=1; i<=n; i++)
{
pre[i]=i; //一共有n个根节点
}
for(i=0; i<m; i++)
{
if(find(pp[i].u)!=find(pp[i].v)) //若两个结点之间没有被连通
{
sum+=pp[i].w;
num++;
mix(pp[i].u,pp[i].v); //连接起两个结点
}
if(num>=n-1) //条数小于节点数
break;
}
cout<<sum<<endl;
}
int main()
{
while(cin>>n>>m)
{
for(i=0; i<m; i++)
{
cin>>pp[i].u>>pp[i].v>>pp[i].w;
}
sort(pp,pp+m,cmp); //对修建公路所需要的费用进行排序
kruskal();
}
}