牛客小白月赛6 挖沟(最小生成树 kruskal)

链接:https://www.nowcoder.com/acm/contest/136/H
来源:牛客网
 

题目描述


    胡队长带领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

裸题 10分钟过

 /*
 qq:1239198605
 ctgu_yyf
        */

#include<iostream>
#include<cstdio>
#include<string>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
struct Edge{
	int u; 
	int v;
	int cost;
};
Edge edge[500005];

int par[100005];
int rankk[100005];
int n,m;
void init(int n)
{
	for(int i=1;i<=n;i++)
	{
		par[i]=i;
		rankk[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)
{
	x=find(x);
	y=find(y);
	if(x==y)
	return ;
	
	if(rankk[x]<rankk[y])
	par[x]=y;
	else
	{
		par[y]=x;
		if(rankk[x]==rankk[y])
		rankk[x]++;
	}
}
bool same(int x,int y)
{
	return find(x)==find(y);
}

bool cmp(const Edge &a,const Edge &b)
{
	return a.cost<b.cost;
}

int kruskal()
{
	int res=0;
	init(n);
	sort(edge+1,edge+1+m,cmp);
	for(int i=1;i<=m;i++)
	{
		if(same(edge[i].u,edge[i].v)==false)
		{
			unite(edge[i].u,edge[i].v);
			res=res+edge[i].cost;
		}
	}
	return res;
}
 
int main()
{
   //ios::sync_with_stdio(false);
   scanf("%d%d",&n,&m);
   
   for(int i=1;i<=m;i++)
   scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].cost);
   
   printf("%d\n",kruskal());


return 0;
}

猜你喜欢

转载自blog.csdn.net/k_koris/article/details/81911154