1034. Head of a Gang (30) (并查集 & map)

来源:互联网 发布:白鲨外设淘宝店好 编辑:程序博客网 时间:2024/05/17 19:14

题目地址

https://www.patest.cn/contests/pat-a-practise/1034

题目描述

One way that the police finds the head of a gang is to check people’s phone calls. If there is a phone call between A and B, we say that A and B is related. The weight of a relation is defined to be the total time length of all the phone calls made between the two persons. A “Gang” is a cluster of more than 2 persons who are related to each other with total relation weight being greater than a given threshold K. In each gang, the one with maximum total weight is the head. Now given a list of phone calls, you are supposed to find the gangs and the heads.

Input Specification:

Each input file contains one test case. For each case, the first line contains two positive numbers N and K (both less than or equal to 1000), the number of phone calls and the weight threthold, respectively. Then N lines follow, each in the following format:

Name1 Name2 Time

where Name1 and Name2 are the names of people at the two ends of the call, and Time is the length of the call. A name is a string of three capital letters chosen from A-Z. A time length is a positive integer which is no more than 1000 minutes.

Output Specification:

For each test case, first print in a line the total number of gangs. Then for each gang, print in a line the name of the head and the total number of the members. It is guaranteed that the head is unique for each gang. The output must be sorted according to the alphabetical order of the names of the heads.

Sample Input 1:

8 59AAA BBB 10BBB AAA 20AAA CCC 40DDD EEE 5EEE DDD 70FFF GGG 30GGG HHH 20HHH FFF 10

Sample Output 1:

2AAA 3GGG 3

Sample Input 2:

8 70AAA BBB 10BBB AAA 20AAA CCC 40DDD EEE 5EEE DDD 70FFF GGG 30GGG HHH 20HHH FFF 10

Sample Output 2:

0

ac 并查集 map,思路见代码

注意题目描述,和输入输出

#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <iostream>#include <string>#include <vector>#include <queue>#include <algorithm>#include <sstream>#include <stack> #include <map> #include <set> using namespace std;const int INF = 0x7fffffff;const int MIN_INF = - INF -1;typedef long long int LL;const int N = 26*26*26 + 1;int n,k;// 每个name都转成intint char2int(char a,char b,char c){    int aa = a - 'A';    int bb = b - 'A';    int cc = c - 'A';    return aa * 26 * 26 + bb * 26 + cc;}// 并查集int fa[N];int find(int x){    if(x == fa[x])        return x;    return fa[x] = find(fa[x]);}void merg(int x,int y){    int xx = find(x);    int yy = find(y);    fa[xx] = yy;}// 结果集合struct ansData{    int abc;    char a,b,c;    int cnt;};// 排序bool cmp(ansData a1,ansData a2){    return a1.abc < a2.abc;}int main(){    //freopen("in.txt","r",stdin);    while(scanf("%d%d", &n, &k) != EOF)    {        char s1[4],s2[4];        int time;        for(int i=0;i<N;i++)        {            fa[i] = i;        }        map<int,int> mpTime; // 每个人的所有时间        mpTime.clear();        for(int i=0;i<n;i++)        {            scanf("%s%s%d",s1,s2,&time);            int p1 = char2int(s1[0],s1[1],s1[2]);            int p2 = char2int(s2[0],s2[1],s2[2]);            mpTime[p1] += time;            mpTime[p2] += time;            if(find(p1) != find(p2)) // 并查集合并            {                merg(p1,p2);            }        }        int ansCnt = 0;        map<int,int> ansM;         map<int,int> ansMax;        map<int,int> mpCnt; // 每个cluster的人数        map<int,int> mpTotalTime; // 每个cluster的总时间,算了两次        map<int,int>::iterator it = mpTime.begin();        while(it != mpTime.end())        {            int name = it->first;            int costTime = it->second;            int faT = find(name);            mpCnt[faT] ++;            mpTotalTime[faT] += costTime;            ++it;        }        // 根据上一步的结果,统计结果        it = mpCnt.begin();        while(it != mpCnt.end())        {            if(mpCnt[it->first] > 2 && mpTotalTime[it->first] > 2*k)            {                ansCnt ++;                ansM[it->first] = mpCnt[it->first];            }else{                ansM[it->first] = -1;            }            ++it;        }        if(ansCnt == 0)        {            printf("0\n");            continue;        }        // 统计每个cluster 最长时间的name是哪一个        map<int,int> ansName;        map<int,int>::iterator it2 = mpTime.begin();        while(it2 != mpTime.end())        {            int name = it2->first;            int costTime = it2->second;            int faT = find(name);            if(ansM[faT] > 2 && costTime > ansMax[faT])            {                ansMax[faT] = costTime;                ansName[faT] = name;            }            ++it2;        }        // 按照自定的数据类型,存储结果并排序        vector<ansData> vs;        map<int,int>::iterator it3 = ansName.begin();        while(it3 != ansName.end())        {            ansData ansTmp;            ansTmp.a = it3->second / (26*26) + 'A';            ansTmp.b = (it3->second / 26 - (ansTmp.a - 'A')* 26) + 'A';            ansTmp.c = it3->second % 26 + 'A';            ansTmp.abc = it3->second;            ansTmp.cnt = mpCnt[it3->first];            vs.push_back(ansTmp);            it3++;        }        sort(vs.begin(),vs.end(),cmp);        // 打印结果        printf("%d\n", ansCnt);        vector<ansData>::iterator ansit = vs.begin();        while(ansit != vs.end())        {            printf("%c%c%c %d\n", ansit->a,ansit->b,ansit->c,ansit->cnt);            ansit++;        }    }    return 0;}

ac2,精简代码
C++ string , map, 并查集

#include <cstdio>#include <memory>#include <cstdlib>#include <cmath>#include <cstring>#include <iostream>#include <string>#include <vector>#include <queue>#include <algorithm>#include <sstream>#include <list>#include <stack> #include <map> #include <set> using namespace std;// freopen("in.txt", "r", stdin);#define INF 0x7fffffffconst int N = 26* 26 * 26 + 5;int n, K;map<string,int> mps2i;map<int,string> mpi2s;int getIntName(string name){    int a = name[0] - 'A';    int b = name[1] - 'A';    int c = name[2] - 'A';    return a * 26 * 26 + b * 26 + c; }map<int,int> mpScore;int fa[N];int Find(int x){    if(x == fa[x])        return x;    return fa[x] = Find(fa[x]);}void Merg(int x,int y){    int xx = Find(x);    int yy = Find(y);    fa[xx] = yy;}struct data{    string name;    int cnt;};bool cmp(data d1,data d2){    return d1.name < d2.name;}int main( ){    //freopen("in.txt", "r", stdin);    while(scanf("%d%d", &n, &K) != EOF)    {        for(int i=0;i<N;i++)            fa[i] = i;        mps2i.clear();        mpi2s.clear();        mpScore.clear();        string name1,name2;        int score;        for(int i=0;i<n;i++)        {            cin >> name1 >> name2 >> score;            int intName1 = getIntName(name1);            mps2i[name1] = intName1;            mpi2s[intName1] = name1;            int intName2 = getIntName(name2);            mps2i[name2] = intName2;            mpi2s[intName2] = name2;            mpScore[intName1] += score;            mpScore[intName2] += score;            if(Find(intName1) != Find(intName2))            {                Merg(intName1, intName2);            }        }        map<int,vector<int>> mpGang;        map<int,int> mpGangScore;        map<int,int>::iterator it = mpScore.begin();        while(it != mpScore.end())        {            int tmpNameInt = it->first;            int tmpFa = Find(tmpNameInt);            mpGang[tmpFa].push_back(tmpNameInt);            mpGangScore[tmpFa] += it->second;            ++it;        }        int ansCnt = 0;        vector<data> vans;        map<int,int>::iterator it2 = mpGangScore.begin();        while(it2 != mpGangScore.end())        {            int tLen = mpGang[it2->first].size();            if(it2->second > 2*K && tLen > 2)            {                ansCnt++;                int maxScore = -1;                int tmpId;                for(int j =0;j<tLen;j++)                {                    int id = mpGang[it2->first][j];                    if(mpScore[id] > maxScore){                        maxScore = mpScore[id];                        tmpId = id;                    }                }                data dt;                dt.cnt = tLen;                dt.name = mpi2s[tmpId];                vans.push_back(dt);            }            ++it2;        }        printf("%d\n",ansCnt);        if(ansCnt > 0)        {            sort(vans.begin(), vans.end(), cmp);            for(int i=0;i<ansCnt;i++)            {                cout << vans[i].name << " " << vans[i].cnt << endl;            }        }    }    return 0;}
0 0