您的位置:首页 > 其它

蓝桥杯_算法训练 安慰奶牛

2018-03-23 20:15 363 查看
问题描述Farmer John变得非常懒,他不想再继续维护供奶牛之间供通行的道路。道路被用来连接N个牧场,牧场被连续地编号为1到N。每一个牧场都是一个奶牛的家。FJ计划除去P条道路中尽可能多的道路,但是还要保持牧场之间 的连通性。你首先要决定那些道路是需要保留的N-1条道路。第j条双向道路连接了牧场Sj和Ej(1 <= Sj <= N; 1 <= Ej <= N; Sj != Ej),而且走完它需要Lj的时间。没有两个牧场是被一条以上的道路所连接。奶牛们非常伤心,因为她们的交通系统被削减了。你需要到每一个奶牛的住处去安慰她们。每次你到达第i个牧场的时候(即使你已经到过),你必须花去Ci的时间和奶牛交谈。你每个晚上都会在同一个牧场(这是供你选择的)过夜,直到奶牛们都从悲伤中缓过神来。在早上 起来和晚上回去睡觉的时候,你都需要和在你睡觉的牧场的奶牛交谈一次。这样你才能完成你的 交谈任务。假设Farmer John采纳了你的建议,请计算出使所有奶牛都被安慰的最少时间。
输入格式第1行包含两个整数N和P。
接下来N行,每行包含一个整数Ci。
接下来P行,每行包含三个整数Sj, Ej和Lj。
输出格式输出一个整数, 所需要的总时间(包含和在你所在的牧场的奶牛的两次谈话时间)。样例输入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样例输出176数据规模与约定5 <= N <= 10000,N-1 <= P <= 100000,0 <= Lj <= 1000,1 <= Ci <= 1,000。

       首先说明,这个题中给的数据是错误的,我在一片博客中又找了一组新的数据,这里要自己必须想到的解题思路就是:我们把路径中花费的时间,换成走这段路需要的时间+问候两边牛要的时间,因为到一个地方不管有没有来过都要慰问一下,这样的话,我们只需要在最后+慰问起点的那一点时间就够了。#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <map>
#include <queue>
#include <cmath>
#include <math.h>
#define INF 0x3f3f3f3f
#define Lson L,mid,rt<<1
#define Rson mid+1,R,rt<<1|1

using namespace std;
typedef long long ll;
const int MAXN = 101000;
int n,p,pos,all_time; //n和农场,P条路
int c[MAXN];
int pre[MAXN];
struct Node
{
int x,y;
int cost;
bool flag;
bool operator <(const Node a) const
{
return cost<a.cost;
}
}node[MAXN];

int Find(int x)
{
int k = x;
while(k!=pre[k])
{
k = pre[k];
}
int temp;
while(pre[x] != k)
{
temp = pre[x];
pre[x] = k;
x = temp;
}
return k;
}

bool Same(int x,int y)
{
return Find(x) == Find(y);
}

void Union(int x,int y)
{
x = Find(x);
y = Find(y);
pre[x] = y;
}
void Init()
{
scanf("%d%d",&n,&p);
int max_cost = INF;
all_time = 0;
for(int i =1 ;i <= n;i ++)
{
scanf("%d",&c[i]);
all_time += c[i];
if(c[i] < max_cost)
{
max_cost = c[i];
pos = i;
}
}
all_time += c[pos];
for(int i =1 ;i <= p;i ++)
{
scanf("%d%d%d",&node[i].x,&node[i].y,&node[i].cost);
node[i].cost = node[i].cost*2;
node[i].cost += c[node[i].x] + c[node[i].y];
node[i].flag = false;
}

for(int i = 1;i <= n;i ++)
pre[i] = i;
}

void Solve()
{
sort(node+1,node+1+p);
int all_cost = 0;
for(int i =1 ;i <= p;i ++)
{
if(!Same(node[i].x,node[i].y))
{
Union(node[i].x,node[i].y);
node[i].flag = true;
all_cost += node[i].cost;
}
}
int a[MAXN];
for(int i = 1;i <= p;i ++)
{
if(node[i].flag)
{
a[node[i].x] ++;
a[node[i].y] ++;
}
}
printf("%d\n",all_cost+c[pos]);
}

int main()
{
Init();
Solve();
return 0;
}
参考文献:
博客:https://www.cnblogs.com/xl1027515989/archive/2014/03/16/3603151.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息