PAT1034. Head of a Gang ——离散化+并查集

题意:成员A与成员B通话 ,成员B与成员C通话,则 ABC即为一个团伙,一共有若干个团伙,每个团伙的人数大于2且相互通话时间超过一定值即为黑帮,每个黑帮伙里有一个BOSS,boss是与各个成员打电话最多的那一个,找出所有黑帮boss跟与之相应成员数,按字典序排列。

 

分析:通话姓名是字符串,不好直接构图,离散化一下,在用并查集确定团伙,在查找黑帮与BOSS

PAT1034. Head of a Gang ——离散化+并查集
#include<stdio.h>

#include<iostream>

#include<algorithm>

#include<stack>

#include<map>

#include<string>

using namespace std;



int bossLen[2099];

int oneLen[2099];

int Link[2099];

int n,K;

map<string,int>mm1; // 字符串对应数字

map<int,string>mm2;//数字对应字符串

int f[2099];

int point[2099];

int index=0;



struct data{

    string name;

    int linkN;

}node[2099];

int headNum=0;



int find(int n){

    if(f[n]==-1)return n;

    return f[n]=find(f[n]);

}



int um(int a,int b){

    int fa=find(a),fb=find(b);

    if(fa==fb)return 0;

    else f[fa]=fb;

}



void init(){

    int i;

    for(i=1;i<=2009;i++){

        bossLen[i]=0;

        oneLen[i]=0;

    }

    for(i=0;i<=2009;i++){

        f[i]=-1;

    }



    string str1,str2;

    for(i=1;i<=n;i++){

        cin>>str1;

        int ll,rr;

        if(mm1.find(str1)==mm1.end()){

            index++;

            mm1[str1]=index;

            mm2[index]=str1;

            ll=index;

        }else{

            ll=mm1[str1];

        }

        cin>>str2;

        if(mm1.find(str2)==mm1.end()){

            index++;

            mm1[str2]=index;

            mm2[index]=str2;

            rr=index;

        }else{

            rr=mm1[str2];

        }

        int temp;

        scanf("%d",&temp);

        bossLen[ll]+=temp;

        bossLen[rr]+=temp;

        oneLen[ll]+=temp;

        um(ll,rr);

    }

}



int cmp(data x,data y){

    return x.name<y.name;

}



void cal(){

    int i;



    int useground[2099];

    int hash1[2099];

    int groundLen[2099];

    int hashLen[2099];

    for(i=1;i<=index;i++){

        useground[i]=0;

        Link[i]=0;

        point[i]=find(i);

        hash1[i]=0;

        hashLen[i]=0;

    }

    for(i=1;i<=index;i++){

        hash1[point[i]]++;

    }



    for(i=1;i<=index;i++){

        hashLen[point[i]]+=oneLen[i];

        Link[i]=hash1[point[i]];

    }



    for(i=1;i<=index;i++){

        groundLen[i]=hashLen[point[i]];

        if(Link[i]>2&&groundLen[i]>K){

            if(useground[point[i]]==1)continue;//该团伙遍历过,就不要遍历了

            headNum++;



            int rk,max=0,k;

            for(k=1;k<=index;k++){//找团队中单人最多通话,就是老大

                if(point[i]!=point[k])continue;

                if(bossLen[k]>max){

                    max=bossLen[k];

                    rk=k;

                }

            }

            useground[point[rk]]=1;

            node[headNum].linkN=Link[rk];

            node[headNum].name=mm2[rk];

        }

    }

    printf("%d\n",headNum);

    sort(&node[1],&node[headNum+1],cmp);

    for(i=1;i<=headNum;i++){

        cout<<node[i].name<<" "<<node[i].linkN<<endl;

    }



}



int main()

{

    while(scanf("%d%d",&n,&K)!=EOF){

        int i;

        init();

        cal();

    }



    return 0;

}
View Code

 

你可能感兴趣的:(head)