安慰员工(cheer.pas/c/cpp)
【题目描述】
LongDD 变得非常懒, 他不想再继续维护供员工之间供通行的道路. 道路被用来连
接N(5 <= N <= 10,000)个房子, 房子被连续地编号为 1..N. 每一个房子都是一个
员工的家. LongDD计划除去 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)的时间和员工交谈.
你需要从某一个房子出发(这是供你选择的),并最终回到这个房子。期间,你要经
过每个房子至少一次,并且当你经过某个房子的时候,你必须和这个房子里的员工
交谈(即使你已经到过).
假设LongDD 采纳了你的建议, 请计算出使所有员工都被安慰的最少时间.
【输入格式】
* 第 1 行: 用空格隔开的两个整数 N和P
* 第 2..N+1 行: 第i+1 行包含了一个整数: C_i
* 第 N+2..N+P+1 行: 第 N+j+1 行包含用空格隔开的三个整数: S_j, E_j 和 L_j
【输入样例】
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
【题目描述】
LongDD 变得非常懒, 他不想再继续维护供员工之间供通行的道路. 道路被用来连
接N(5 <= N <= 10,000)个房子, 房子被连续地编号为 1..N. 每一个房子都是一个
员工的家. LongDD计划除去 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)的时间和员工交谈.
你需要从某一个房子出发(这是供你选择的),并最终回到这个房子。期间,你要经
过每个房子至少一次,并且当你经过某个房子的时候,你必须和这个房子里的员工
交谈(即使你已经到过).
假设LongDD 采纳了你的建议, 请计算出使所有员工都被安慰的最少时间.
【输入格式】
* 第 1 行: 用空格隔开的两个整数 N和P
* 第 2..N+1 行: 第i+1 行包含了一个整数: C_i
* 第 N+2..N+P+1 行: 第 N+j+1 行包含用空格隔开的三个整数: S_j, E_j 和 L_j
【输入样例】
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
这道题比较水但是当时出现了特别奇葩的错误
教训:记得判断边界(无论你如何相信不会超出边界 但很有可能他还是会超出边界)
裸的最小生成树吧
由于去掉边后形成的是一个有回路的树
每条边必然被使用两次
所以边权值为二倍长度 + 两端点的代价
而出发点并没有计算在内 所以最后加上出发点的代价
也就是所有代价中最小的一个
代码如下
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
using namespace std;
int N, P;
int Cost[100005];
int Father[100005];
int Low = 0x3f3f3f3f;
int Mst();
void init();
int Get_Father(int x);
int ans;
struct Edge
{
int u, v, d;
bool operator < (const Edge &N) const
{
return d < N.d;
}
}edge[1000005];
inline void Ins(int k)
{
int u, v, d;
scanf("%d%d%d", &u, &v, &d);
d = d + d + Cost[u] + Cost[v];
edge[k].u = u;
edge[k].v = v;
edge[k].d = d;
}
void init()
{
for(int i = 1; i <= N; i++)
{
Father[i] = i;
}
return;
}
inline int Get_Father(int x)
{
if (Father[x] != x)
{
return Father[x] = Get_Father(Father[x]);
}
return x;
}
void init_file()
{
freopen("cheer.in", "r", stdin);
freopen("cheer.out", "w", stdout);
}
void read_data()
{
scanf("%d%d", &N, &P);
for(int i = 1; i <= N; i++)
{
scanf("%d", Cost + i);
Low = min(Low, Cost[i]);
}
for(int i = 1; i <= P; i++)
Ins(i);
sort(edge + 1, edge + 1 + P);
}
int Mst()
{
init();
int time = 1;
int ans = edge[1].d;
int fx = Get_Father(edge[1].u);
int fy = Get_Father(edge[1].v);
int V_t = 0;
Father[fx] = fy;
time++;
while(V_t + 1 < N && time <= P)
{
int fx = Get_Father(edge[time].u);
int fy = Get_Father(edge[time].v);
if (fx != fy)
{
Father[fx] = fy;
ans += edge[time].d;
++V_t;
}
++time;
}
return ans;
}
void work()
{
printf("%I64d", (long long)(Mst() + Low));
}
int main()
{
init_file();
read_data();
work();
return 0;
}