您的位置:首页 > 其它

计蒜客习题:穿越雷区

2018-03-19 15:09 288 查看

问题描述

蒜头君最近迷上了一款 RPG 游戏,这次他要去森林里的 n 个宝藏点收集宝藏,编号从 1 到 n。森林里有 m 条道路连接宝藏点,每条道路上都有数量不等的地雷,蒜头君想从中找出若干条道路,使得任意两个宝藏点都是连通的,这样蒜头君都能访问到每个宝藏点了。另外,由于遇到一个地雷,蒜头君会减少一定的血量。

现在蒜头君知道了这 m 条道路上的地雷数,蒜头君希望挑选若干条道路,使得挑选出的道路,地雷数量之和尽可能小。

输入格式

第一行输入两个整数 n,m(1≤n≤30,000,1≤m≤50,000),表示森林里有 n个宝藏点,m 条道路。两个宝藏点之间可能会有多条道路。

接下来输入 m 行,每行输入三个整数 x,y,z(1≤x,y≤n,0≤z≤1,000),表示 x 和 y 之间有 z 个地雷。

输出格式

输出一行,输出一个整数。表示蒜头君挑出了若干条道路,使得任意两个宝藏点都是连通的,输出道路的地雷数量之和最小值。

样例输入

3 4

1 2 121

1 3 202

2 1 497

2 3 135

样例输出

256

AC代码

#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
int MAXN=30010;
int MAXM=50010;

struct edge {
int u,v,w;
}e[50010];

int dad[30010];
int n,m;

int getdad(int i)
{
if(dad[i]==i)return dad[i];
return dad[i]=getdad(dad[i]);
}

bool cmp(edge a,edge b)
{
return a.w<b.w;
}

int main()
{
for(int i=0;i<=MAXN+5;i++)
{
dad[i]=i;
}
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int x,y,z;
cin>>x>>y>>z;
e[i].u=x;
e[i].v=y;
e[i].w=z;
}
sort(e+1,e+m+1,cmp);
int rest=n;
int ans=0;
for(int i=1;i<=m&&rest>1;i++)
{
if(getdad(e[i].u)!=getdad(e[i].v))
{
dad[getdad(e[i].u)]=getdad(e[i].v);
ans+=e[i].w;
}
}
cout<<ans;
return 0;

}


ad79
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: