并查集_挖沟(求连通全图的最短路径)

链接: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

我的代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[1000000+10];
int par[1000000+10]; 
int n,m;
int i ,j;
struct node{
	int u,v,w;
}arr[1000000+10];
void init()
{
	for(i=1;i<=n;i++)
	par[i]=i;
}
bool cmp(node a,node b)
{
	return a.w<b.w;
}
int find(int x)
{
	if(x==par[x])
	return x;
	else
	return par[x]=find(par[x]);
}
int unite(int x,int y)
{
	int fx=find(x);
	int fy=find(y);
	if(fx!=fy)
	{
		par[fy]=fx;
		return 1;
	}
	return 0;
}
int main()
{
		scanf("%d",&n);
		int ans=0,ant=0;
		int sum=0;
		scanf("%d",&m);
		//m=n*(n-1)/2;
		for(i=1;i<=m;i++)
		{
			scanf("%d%d%d",&arr[i].u,&arr[i].v,&arr[i].w);
		}
		sort(arr+1,arr+m+1,cmp);
		init();
		for(i=1;i<=m;i++)
		{
		 if(unite(arr[i].u,arr[i].v))
		 {
		 	ant++;
		 	sum+=arr[i].w;
		 }	
		 if(ant==n-1)
		 break;
		}
		printf("%d\n",sum);
}

大神代码:

#include<bits/stdc++.h>
using namespace std;
struct edge
{
    int s,t,d;
    bool operator<(const edge& y)const
    {
        return d<y.d;
    }
}e[500005];
int n,m,i,f[100005],ans;
int get(int x)
{
    if(f[x]==x)return x;
    return f[x]=get(f[x]);
}
int main()
{
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++)f[i]=i;
    for(i=1;i<=m;i++)scanf("%d%d%d",&e[i].s,&e[i].t,&e[i].d);
    sort(e+1,e+m+1);
    for(i=1;i<=m;i++)if(get(e[i].s)!=get(e[i].t))
    {
        ans+=e[i].d;
        f[get(e[i].s)]=get(e[i].t);
    }
    cout<<ans<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/aaakkk_1996/article/details/81836581