安慰奶牛
Description
Farmer John变得非常懒, 他不想再继续维护供奶牛之间供通行的道路. 道路被用来连接N(5 <= N <= 10,000)个牧场, 牧场被连续地编号为1..N. 每一个牧场都是一个奶牛的家.FJ计划除去P(N-1 <= P <= 100,000)条道路中尽可能多的道路, 但是还要保持牧场之间的连通性. 你首先要决定那些道路是需要保留的N-1条道路. 第j条双向道路连接了牧场S_j和E_j (1 <= S_j <= N; 1 <= E_j <= N; S_j != E_j),而且走完它需要L_j (0 <= L_j <= 1,000)的时间. 没有两个牧场是被一条以上的道路所连接. 奶牛们非常伤心, 因为她们的交通系统被削减了. 你需要到每一个奶牛的住处去安慰她们. 每次你到达第i个牧场的时候(即使你已经到过), 你必须花去C_i (1 <= C_i <= 1,000)的时间和奶牛交谈. 你每个晚上都会在同一个牧场(这是供你选择的)过夜, 直到奶牛们都从悲伤中缓过神来. 在早上起来和晚上回去睡觉的时候, 你都需要和在你睡觉的牧场的奶牛交谈一次. 这样你才能完成你的交谈任务. 假设Farmer John采纳了你的建议, 请计算出使所有奶牛都被安慰的最少时间. 对于你前10次的提交, 你的程序会在一部分正式的测试数据上运行, 并且返回运行的结果.
Input
* 第 1 行: 用空格隔开的两个整数N和P
* 第 2..N+1 行: 第i+1行包含了一个整数: C_i
* 第 N+2..N+P+1 行: 第 N+j+1 行包含用空格隔开的三个整数: S_j, E_j 和 L_j
Output
* 第 1 行: 一个整数, 所需要的总时间(包含和在你所在的牧场的奶牛的两次谈话时间).
Sample Input
5 7
10
10
20
6
30
1 2 5
2 3 5
2 4 12
3 4 17
2 5 15
3 5 6
4 5 12
Sample Output
176
//source:http://blog.csdn.net/sdj222555/article/details/8241557
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<queue> #include<set> #include<stack> #include<cmath> #include<map> #include<ctime> #define MAX 100001 #define INF (1<<30) using namespace std; int n, m; struct EDGE{ int u, v, len; }; EDGE edge[MAX]; int par[MAX];//并查集,父亲 int c[MAX]; bool cmp(EDGE x, EDGE y){ return x.len < y.len; } int find(int x) { if (par[x] == x)return x; else return par[x] = find(par[x]); } int main() { int x, y, z, i, sum, fx, fy; cin >> n >> m; int mi = INF; for (i = 1; i <= n; i++){ cin >> c[i]; mi = min(mi, c[i]); par[i] = i; } for (i = 1; i <= m; i++) { cin >> x >> y >> z; edge[i].u = x; edge[i].v = y; edge[i].len = z * 2 + c[x] + c[y]; } sort(edge + 1, edge + m + 1, cmp); sum = 0; for (i = 1; i <= m; i++) { fx = find(edge[i].u); fy = find(edge[i].v); if (fx != fy) { sum += edge[i].len; par[fx] = fy; } } cout << sum + mi << endl; system("pause"); return 0; }
用并查集做最小生成树,感脚好清新!