题目描述
胡队长带领HA实验的战士们玩真人CS,真人CS的地图由一些据点组成,现在胡队长已经占领了n个据点,为了方便,将他们编号为1-n,为了隐蔽,胡队长命令战士们在每个据点出挖一个坑,让战士们躲在坑里。由于需要在任意两个点之间传递信息,两个坑之间必须挖出至少一条通路,而挖沟是一件很麻烦的差事,所以胡队长希望挖出数量尽可能少的沟,使得任意两个据点之间有至少一条通路,顺便,尽可能的∑d[i][j]使最小(其中d[i][j]为据点i到j的距离)。
输入描述:
第一行有2个正整数n,m,m表示可供挖的沟数。 接下来m行,每行3个数a,b,v,每行描述一条可供挖的沟,该沟可以使a与b连通,长度为v。
输出描述:
输出一行,一个正整数,表示要使得任意两个据点之间有一条通路,至少需要挖长的沟。(数据保证有解)
示例1
输入
2 2 1 2 1 1 2 3
输出
1
示例2
输入
3 3 1 2 3 2 3 4 1 3 5
输出
7
备注:
对于100%的测试数据: 1 ≤ n ≤ 100000 1 ≤ m ≤ 500000 1 ≤ v ≤ 10000
思路:题目大意为通过最短的边权之和使所有点联通,因此此题明显为一个最小生成树的裸题,因为题目所给的为一个稀疏图,因此可以用kruskal算法求解
AC代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int N=100010,M=500010;
struct Edge
{
int a,b,w;
bool operator<(const Edge&t)const{
return w<t.w;
}
}edge[M];
int n,m;
int p[N];
int find(int x)
{
if(x==p[x])
return x;
return p[x]=find(p[x]);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++)
{
int a,b,w;
scanf("%d%d%d",&a,&b,&w);
edge[i]={a,b,w};
}
sort(edge,edge+m);
for(int i=1;i<=n;i++)
p[i]=i;
int res=0;
for(int i=0;i<m;i++)
{
int a=find(edge[i].a),b=find(edge[i].b),w=edge[i].w;
if(a!=b)
{
p[a]=b;
res+=w;
}
}
cout<<res<<endl;
}