安慰奶牛

来源:互联网 发布:snow拍照软件 编辑:程序博客网 时间:2024/05/01 21:54

题目连接:http://lx.lanqiao.org/problem.page?gpid=T16

思路:这就是一道简单的最小生成树的问题可是我们要注意的是  当我们去了一个地方我们要走回来的所以我们要把两个点的距离乘2

然后求出最小的那个用时最短的牧场过夜 加上去就可以了  

下面看代码:

#include<stdio.h>#include<iostream>#include<string.h>#include<algorithm>using namespace std;#define max(a,b)((a > b)?(a):(b))#define MAX 0x7fffffffstruct node{int u;int v;int cap;}edge[100100];  //每条路的属性的int d[100100];int p[100100];   //记录每个点的值的int f[100100];   //记录每个点的父亲节点的int M, n, m;bool cmp(node a,node b){return a.cap < b.cap;}void add(int from,int to,int cap){edge[M].u = from;edge[M].v = to;edge[M].cap = cap * 2 + p[from] + p[to]; //这个地方是去然后还得回来所以乘2M++;}int find(int x){if(f[x] == x)return f[x];return f[x] = find(f[x]);}void kruskal(){int i;for(i = 1;i <= n;i++){f[i] = i;d[i] = 0;}int u,v,fu,fv,sum = 0;for(i = 0;i < M;i++){u = edge[i].u;v = edge[i].v;fu = find(u);fv = find(v);if(fu == fv)continue;//如果相同的话 那么久直接加就可以了sum += edge[i].cap;f[fu] = fv;   //这个地方别忘了 一定要把父亲节点给写了//d[u]++;//d[v]++;}int tmp = MAX;for(i = 1;i <= n;i++){if(tmp > p[i])tmp = p[i];}printf("%d\n",sum + tmp);}int main(){int i;int s,t,c;while(~scanf("%d%d",&n,&m)){for(i = 1;i <= n;i++){scanf("%d",&p[i]);}for(i = 0;i < m;i++){scanf("%d%d%d",&s,&t,&c);add(s,t,c);}sort(edge,edge + M,cmp);kruskal();}return 0;}


0 0
原创粉丝点击