Pat1034

来源:互联网 发布:创业网络平台建设 编辑:程序博客网 时间:2024/04/30 20:22

这题的话其实不是特别难,但是如果没有特别好的方法,很难拿到满分,而且比较麻烦,但是会一点小小的搜索,拿个十几分还是可以的,比较恶心的题目没有告诉你有多少个点,如果map的话,最多就2000个不同的点,因为它只给你1000条边,我第一次看到这题想到的是搜索,搜的一塌糊涂,拿了17分,后来看到王道上的人都是用并查集做的,所以自己也试了下并查集的做法,这题用并查集能较好的解决2个问题:1在并查集选择father时,优化了的并查集选择树儿子较多的为father,这题可以选择通信量较大的为father 2如何计算一个集合的总通信量,只要枚举每条边,找到这条边属于哪个father,把相应的值加上就好。用搜索的话,个人还是没有拿到满分,这里代码就不献丑了,

并查集代码如下:

#include<stdio.h>#include<string.h>#include<iostream>#include<string>#include<map>#include<algorithm>#define N 2001using namespace std;map<string,int>cl;struct node{    string st,ed;    int d;}e[N];int fa[N];int num[N];int tot[N];int t[N];struct ans{    string aa;    int bb;}ans[N];int getfather(int x){if (fa[x] != x)fa[x]=getfather(fa[x]);return fa[x];}void un(int a, int b){    a = getfather(a);    b = getfather(b);    if(a==b)    return;    if(t[a]>t[b])    {        fa[b]=a;        num[a]+=num[b];    }    else    {        fa[a]=b;        num[b]+=num[a];    }}int main(){int n,m;while(scanf("%d%d",&n,&m)!=EOF){int i,j;int vnum=0;cl.clear();for(i=1;i<=n;i++){            string a,b;            int t;            cin >> a >> b >> t;            e[i].st = a;            e[i].ed = b;            e[i].d = t;    if(cl.count(e[i].st)==0)    {                ++ vnum;                cl.insert(make_pair(e[i].st,vnum));            }            if(cl.count(e[i].ed)==0)    {                ++ vnum;                cl.insert(make_pair(e[i].ed,vnum));            }        }        for (i=1;i<=vnum;i++)        {            fa[i] = i;            t[i] = 0;            tot[i] = 0;            num[i] = 1;        }for(i=1;i<=n;i++){            t[cl[e[i].st]]+=e[i].d;            t[cl[e[i].ed]]+=e[i].d;        }        for(i=1;i<=n;i++)        un(cl[e[i].st],cl[e[i].ed]);                for(i=1;i<=vnum;i++)        fa[i]=getfather(i);        for(i=1;i<=n;i++){       int father=getfather(cl[e[i].st]);            tot[father]+=e[i].d;        }        int cnt=0;        for (map<string,int>::iterator it = cl.begin();it != cl.end(); it++)        {            int kk=it->second;            if(tot[kk]>m&&num[kk]>=3&&fa[kk]==kk)            {                ans[++cnt].aa=it->first;                ans[cnt].bb=num[kk];            }        }        printf("%d\n",cnt);        for(i=1;i<=cnt;i++)        cout<<ans[i].aa<<" "<<ans[i].bb<<endl;    }    return 0;}

原创粉丝点击