【最小生成树】安慰员工

来源:互联网 发布:基本网络拓扑图 编辑:程序博客网 时间:2024/06/10 17:13
安慰员工(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 

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;}


原创粉丝点击