NKOI 1228 丛林道路

来源:互联网 发布:什么软件可以涂鸦照片 编辑:程序博客网 时间:2024/04/28 19:30

丛林道路

Time Limit:10000MS  Memory Limit:65536K
Total Submit:94 Accepted:73
Case Time Limit:1000MS

Description

热带小岛“拉格瑞珊”的酋长面临着一个问题:很久以前,通过大量外来资金援助,在岛上的村庄之间修建了很多道路。但是由于岛上的丛林生长得特别快,掩盖了很多公路,而如此庞大的公路网络维护起来费用就相当昂贵。小岛的管理委员会必须选择停止某些公路的维护工作。下面左边的地图显示了现在正在使用的道路和每条道路每个月需花费的维护费用。酋长要告诉委员会只保留哪些公路便可连接岛上的所有村庄并且使得每个月的维护费用总和最少。下面右边的地图便是最便宜的公路连接方案。你的任务就是写一个程序来解决这个问题。

Input

第一行,一个数字n(1接下来n-1按字母表顺序排列。每行开头是一个大写字母,表示村庄的编号。接着是一个数字k,表示连接该村庄的公路数量。如果公路条数k不为0,则后面是和该村庄直接相连的k个村庄的编号(按字母表顺序排列)和维护连接这两个村庄的公路的花费。
注:每个村庄最多有15条公路和其他村庄直接相连,每条公路的维护费用不超过75,公路的总条数不超过100

Output

只有一行:连接所有村庄的公路的最小维护费用。

Sample Input

9A 2 B 12 I 25B 3 C 10 H 40 I 8C 2 D 18 G 55D 1 E 44E 2 F 60 G 38F 0G 1 H 35H 1 I 35

Sample Output

216

Source


最小生成树,主要问题就在于输入的时候要注意把大写字母分别表示成1,2,……,然后用数组把边存起来

#include<cstdio>
#include<cstdlib>
#include<iostream>
using namespace std;
const int maxn=200005,maxm=500005;
int fath[maxn],x[maxm],y[maxm],z[maxm],N,M;
inline void _getnum(int &xx){
    char tt=getchar();
    while(tt<'0'||tt>'9')tt=getchar();
    for(xx=0;tt>='0'&&tt<='9';tt=getchar())xx=xx*10+(tt-'0');
}
void _qst(int l,int r){
    int i,j,m,t;
    i=l;j=r;
    m=z[(i+j)>>1];
    while(i<=j){
        while(z[i]<m)i++;
        while(z[j]>m)j--;
        if(i<=j){
            t=x[i];x[i]=x[j];x[j]=t;
            t=y[i];y[i]=y[j];y[j]=t;
            t=z[i];z[i]=z[j];z[j]=t;
            i++;j--;
        }
    }
    if(i<r)_qst(i,r);
    if(l<j)_qst(l,j);
}//也可用sort,但是要注意用结构体,否则很麻烦
int _getfath(int i){
    if(fath[i]!=i)fath[i]=_getfath(fath[i]);
    return fath[i];
}
int main(){
    int i,j,ans=0,X,Y,k,l,cnt=0;
    char c,b;
    _getnum(N);
    N--;
    for(i=1;i<=N;i++){
        cin>>c>>k;
        for(j=1;j<=k;j++){
            cin>>b>>l;
            x[++cnt]=int(c)-64;
            y[cnt]=int(b)-64;
            z[cnt]=l;
        }
    }
    _qst(1,cnt);
    for(i=1;i<=N;i++)fath[i]=i;
    for(i=1;i<=cnt;i++){//一共有cnt条边,因此要讨论cnt次
        X=_getfath(x[i]);
        Y=_getfath(y[i]);
        if(X!=Y)fath[X]=Y,ans+=z[i];//不是同一个爸爸要合并成一个爸爸
    }
    printf("%d",ans);
}

0 0
原创粉丝点击