poj1251 Jungle Roads Kruskal算法+并查集

时限: 1000MS   内存限制: 10000K
提交总数: 37001   接受: 17398

描述


热带岛屿拉格里山的首长有个问题。几年前,大量的外援花在了村庄之间的额外道路上。但是丛林不断地超越道路,因此庞大的道路网太昂贵而无法维护。老年人理事会必须选择停止维护一些道路。左上方的地图显示了目前正在使用的所有道路,以及每月维护这些道路的费用。当然,即使路线不像以前那么短,也需要采取某种方式在所有村庄之间保持通行。长老院长想告诉长老委员会每月要花多少钱才能维持连接所有村庄的道路。在上面的地图中,这些村庄被标记为A到I。右边的地图显示了可以最便宜地维护的道路,每月可节省216英亩。您的任务是编写一个解决此类问题的程序。

输入

输入由1到100个数据集组成,后面是仅包含0的最后一行。每个数据集都从仅包含数字n的行开始,n是村庄的数目,1 <n <27,并标记了村庄字母的前n个字母大写。每个数据集都以n-1行完成,这些行以字母顺序的村庄标签开头。最后一个村庄没有电话。村庄的每条线均以村庄标签开头,后跟从该村庄到带有字母标签的村庄的道路的数量k。如果k大于0,则该行以k条道路中的每条道路的数据继续。每条道路的数据是道路另一端的村庄标签,其后是道路的每月维护成本(以acms为单位)。维护成本将为小于100的正整数。该行中的所有数据字段均由单个空格分隔。公路网将始终允许所有村庄之间的旅行。该网络永远不会超过75条道路。到其他村庄的村庄中,没有一条道路会超过15条(在字母表中的前后)。在下面的示例输入中,第一个数据集与上面的地图一起显示。

产量

每个数据集的输出为每行一个整数:维护连接所有村庄的道路系统的每月最低费用(以aacms计)。警告:检查每条可能的道路的暴力解决方案都不会在一分钟的时间内完成。

样本输入

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

样本输出

216 
30

资源

裸题,看不懂的话多看看图即可!

#include<iostream>
#include<queue>
#include<algorithm>
#include<set>
#include<cmath>
#include<cstdio>
//---------------------------------Sexy operation--------------------------//

#define cini(n) scanf("%d",&n)
#define dis(a,b,c,d) ((double)sqrt((a-c)*(a-c)+(b-d)*(b-d)))
using namespace std;
//___________________________Dividing Line__________________________________/#
#define N 105
using namespace std;

int father[28];
int rank[28];
int sum;
struct edge
{
    int st;
    int ed;
    int w;
        bool operator< (const edge x)const
    {
        return w<x.w;
    }
} e[400];
int top = 0;
int find(int x)
{
	if(x != father[x])
		father[x] =  find(father[x]);
	return father[x];
}
void addEdge(int x, int y, int z)
{
    e[top].st = x;
    e[top].ed = y;
    e[top].w = 	z;
    top++;
}
int main()
{
    int n,cnt,ans;
    char a,c;
    int edgeNum;
    int weight1;
    while(~scanf("%d",&n)&&n)
    {
        top =cnt=ans=0;
        for(int i = 0; i < n -1 ; i++)
        {
            cin>>a;
            cin>>edgeNum;
            for(int j = 0; j < edgeNum; j++)
            {
                cin>>c;
                cin>>weight1;
                int k = int(c - 'A');
                addEdge(i, k, weight1);
            }
        }
            for(int i = 0; i <= n; i++)
            {
                father[i] = i;
            }
            //cout<<1<<endl;
        sort(e,e+top);
        for(int i=1;i<=n;i++) father[i]=i;
        //cout<<1<<endl;
        for(int i=0;i<top;i++)
        {
            int xx=find(e[i].st),yy=find(e[i].ed);
            if(xx!=yy)
            {
                cnt++;
                ans+=e[i].w;
                father[yy]=xx;
                if(cnt==n-1) break;
            }
        }
        cout<<ans<<endl;
    }
            return 0;
}
posted @ 2019-09-24 22:19  风骨散人  阅读(137)  评论(0编辑  收藏  举报