小白月赛6 H-挖沟 kruskal算法 最小生成树 ʕ •ᴥ•ʔ

   胡队长带领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算法 是基于并查集上的一个算法 当我们用prime() 二维数组不能太大否则内存会超限  所以这个时候需要用 kruskal 算法

#include <cstring>
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <string.h>
#include <map>
#define ll long long
#define pi acos(-1.0)
using namespace std;
int per[500010];
struct ac
{
	int s,e,l;
}r[500010];
int cmp(ac x,ac y)
{
	return x.l<y.l;
}
int find(int w)
{
	if(w==per[w])
	return w;
	return per[w]=find(per[w]);//路径压缩 必须加 
}
int link(int x,int  y)
{
	int nx=find(x),ny=find(y);
	if(nx!=ny)
	{
		per[ny]=nx;
		return 1;
	}
	return 0;
}
int main()
{
	int n,m;
	cin>>n>>m;
	memset(per,0,sizeof(per));
	memset(r,0,sizeof(r));
	for(int i=1;i<=n;i++)
	{
		per[i]=i;
	}
	for(int i=1;i<=m;i++)
	{
		cin>>r[i].s>>r[i].e>>r[i].l;
	}
	sort(r+1,r+m+1,cmp);
	ll ans=0;
	for(int i=1;i<=m;i++)
	{
		if(link(r[i].s,r[i].e))
		ans+=r[i].l;
	} 
	cout<<ans<<endl;
}

猜你喜欢

转载自blog.csdn.net/henucm/article/details/81837349
今日推荐