中中救援队

题目描述

中中酷爱滑雪,某日突发奇想,带领所有BDEZ的OIER去Alps滑雪,不幸的是,中中和OIER们遭遇了雪崩,除了中中,所有的OIER们都埋在了雪坑里,此时,中中救援队闪亮登场~!(中中救援队只有中中一个人!Orz!)

雪崩之后,出现了N个雪坑,每个雪坑都有一名OIER深陷其中,只有中中幸免,现在中中找到了M条双向道路,每条道路都会连接两个雪坑,但是,由于中中是路痴(-_-||),所以中中希望去除M条道路中尽可能多的道路,但是还要保证任一雪坑都能到达其他的雪坑,所以要先选择留下N-1条道路,中中可以从任意一个雪坑出发,并且任务完成后要回到出发点(起点的雪坑和终点的雪坑也需要消耗体力),而且中中只记得他选择的道路 中中每到一个雪坑i,都会消耗一定的体力值t[i],即使这个雪坑的OIER已被救出。第j条道路连接x,y两个雪坑,而从x到达y也需要消耗体力值energy 由于时间紧迫,中中请你这名OIER帮助他计算下救出这N名OIER所消耗的最小体力值是多少

输入格式

输入第一行两个整数N和M,表示有N名OIER,M条连接的道路

接下来N行,每行一个整数t[i],表示第i个雪坑需要消耗中中的体力值

然后M行,每行三个整数x,y,energy,表示从x坑滑到y坑需要消耗的体力值为energy

输出格式

第1行,一个整数,为中中消耗的最小体力值

样例

样例输入

5 7
6
5
13
8
18
4 1 7
5 2 5
1 5 16
2 3 20
3 1 18
4 3 12
2 4 15

样例输出

154

数据范围与提示

对于30%的数据 5<=N<=100,N-1<=M<=500 1<=t[i]<=100 x<=N,y<=N,x<=y,1<=energy<=100

对于全部数据 5<=N<=10000,N-1<=M<=100000 1<=t[i]<=1000 x<=N,y<=N,x<=y,1<=energy<=1000

结果保证不超过 (2^31-1)

code

#include <bits/stdc++.h>
using namespace std;
const int maxn=100000+10;
const int INF=0x3f3f3f3f;
struct node{
	int from,to,dis;
}e[maxn];
int fa[maxn],t[maxn];
inline int find(int rt) {return fa[rt]==rt?rt:fa[rt]=find(fa[rt]);}
bool cmp(node a,node b) {return a.dis<b.dis;}
int main(){
	int n,m;
	cin>>n>>m;int ans=INF;
	for(int i=1;i<=n;i++) {cin>>t[i];fa[i]=i;ans=min(ans,t[i]);}
	for(int i=1;i<=m;i++) {cin>>e[i].from>>e[i].to>>e[i].dis;e[i].dis+=e[i].dis+t[e[i].from]+t[e[i].to];}
	sort(e+1,e+m+1,cmp);
	for(int i=1;i<=m;i++) {
		int u=e[i].from,v=e[i].to;
		if(find(u)!=find(v)) fa[fa[u]]=v,ans+=e[i].dis;
	}
	return cout<<ans<<endl,(0 ^ 0);
}
原文地址:https://www.cnblogs.com/hellohhy/p/13332913.html