51Nod_1212 无向图最小生成树
http://www.51nod.com/Challenge/Problem.html#!#problemId=1212
题目
N个点M条边的无向连通图,每条边有一个权值,求该图的最小生成树。
输入
第1行:2个数N,M中间用空格分隔,N为点的数量,M为边的数量。(2 <= N <= 1000, 1 <= M <= 50000);第2 - M + 1行:每行3个数S E W,分别表示M条边的2个顶点及权值。(1 <= S, E <= N,1 <= W <= 10000)
输入
输出最小生成树的所有边的权值之和。
样例输入
9 14
1 2 4
2 3 8
3 4 7
4 5 9
5 6 10
6 7 2
7 8 1
8 9 7
2 8 11
3 9 2
7 9 6
3 6 4
4 6 14
1 8 8
样例输出
37
分析
使用kruskal算法进行求解,模板题
C++程序
#include<iostream>
#include<queue>
using namespace std;
const int N=1005;
//并查集
int pre[N];
void init(int n)
{
for(int i=0;i<=n;i++)
pre[i]=i;
}
int find(int x)
{
int r=x;
while(r!=pre[r])
r=pre[r];
//路径压缩
while(x!=pre[x]){
int i=pre[x];
pre[x]=r;
x=i;
}
return r;
}
bool join(int x,int y)
{
int fx=find(x);
int fy=find(y);
if(fx!=fy){
pre[fx]=fy;
return true;
}
return false;
}
struct Edge{
int u,v,w;
Edge(){}
Edge(int u,int v,int w):u(u),v(v),w(w){}
bool operator<(const Edge &a)const
{
return w>a.w;
}
};
int main()
{
int n,m,s,e,w;
scanf("%d%d",&n,&m);
init(n);
priority_queue<Edge>q;
while(m--){
scanf("%d%d%d",&s,&e,&w);
q.push(Edge(s,e,w));
}
int ans=0,cnt=0;
while(!q.empty()){
Edge a=q.top();
q.pop();
if(join(a.u,a.v)){
ans+=a.w;
cnt++;
if(cnt==n-1)
break;
}
}
printf("%d\n",ans);
return 0;
}