1034 Head of a Gang (30 分)——甲级(连通分量+map)

14 篇文章 0 订阅
9 篇文章 0 订阅

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 threthold 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 59
AAA BBB 10
BBB AAA 20
AAA CCC 40
DDD EEE 5
EEE DDD 70
FFF GGG 30
GGG HHH 20
HHH FFF 10
Sample Output 1:
2
AAA 3
GGG 3
Sample Input 2:
8 70
AAA BBB 10
BBB AAA 20
AAA CCC 40
DDD EEE 5
EEE DDD 70
FFF GGG 30
GGG HHH 20
HHH FFF 10
Sample Output 2:
0

题目大意:可以大概理解为警察找犯罪团伙,犯罪团伙里的人会互相通话。

  • 两个人通话定义为一个relation;
  • 两个人互相通话的总时间定义为the weight of a relation;
  • 如果说一个犯罪团伙里的人超过2个、并且weights of all relations大于一个给定的数k的话,这个团伙定义为一个gang;
  • 这个团伙中涉及通话时长最长的人定义为这个gang的head。

现在要求输出gang的个数,每个gang的head和人数。

os:题目是看懂了,就是在做题的时候碰到字符串就觉得很棘手。。。今天对map有了更深入的了解,所以做起来就顺利多了。

题解图示:
对于第一组样例
在这里插入图片描述
可以看到:

  1. gang实际上是一个图的连通分量;
  2. the relation of weight实际上是无向图的边权;
  3. head实际上是点权最多的点。

思路:

  1. 用map存图。键为图中的点,值为一个结构体,包括:这个点的点权、这个点的邻接点;
  2. 用dfs遍历每个连通分量,并且根据题目要求把符合要求的点和集团人数记录下来;
  3. 输出结果。

ps:每条边的边权实际上可以看作两个点的点权之和/2,所以不用存边权。

代码如下:

#include <iostream>
#include <vector>
#include <map>
using namespace std;
struct node
{
    int weight;
    vector<string>v;
    node()
    {
        weight = 0;
    }
};
map<string, node>m;/* 存图:类似邻接表的方式 */
map<string, int>res;/* 存答案:点、集团人数 */
map<string, bool>book;/* 标记数组 */
int cnt, sum, maxweight;/* cnt:每个连通分量的点的个数,即集团人数 */
					    /* sum:连通分量的点权之和 */
					    /* maxheight:记录最大的点权,即可能是head的人的点权 */
string ans;/* 记录head */
void dfs(string name)
{
    cnt++;
    book[name] = 1;
    sum += m[name].weight;
    if(maxweight < m[name].weight)
    {
        ans = name;
        maxweight = m[name].weight;
    }
    vector<string>temp = m[name].v;
    int i;
    for(i=0; i<temp.size(); i++)
    {
        if(!book[temp[i]])
            dfs(temp[i]);
    }
}
int main()
{
    int n, k;
    cin >> n >> k;
    int i;
    for(i=1; i<=n; i++)
    {
        string s1, s2;
        int w;
        cin >> s1 >> s2 >> w;
        m[s1].weight += w;
        m[s1].v.push_back(s2);
        book[s1] = 0;

        m[s2].weight += w;
        m[s2].v.push_back(s2);
        book[s2] = 0;
    }
    map<string, node>::iterator it;
    for(it=m.begin(); it!=m.end(); it++)
    {
        if(!book[(*it).first])
        {
            cnt = 0;
            sum = 0;
            maxweight = -1;
            dfs((*it).first);
            if(sum / 2 > k && cnt > 2)
                res[ans] = cnt;
        }
    }
    cout << res.size() << endl;
    map<string, int>::iterator iter;
    for(iter=res.begin(); iter!=res.end(); iter++)
        cout << (*iter).first << " " << (*iter).second << endl;
    return 0;
}

总结
  1. 对于字符串和其他数据的映射,要想到map容器。
  2. 对map有了新的认识:
1.map和set类似,内部会自动排序,并且按照键升序排序。

2.map数据的插入
  (1).用insert函数插入pair数据:m.insert(pair<int, int>(1, 1));
  (2).用insert函数插入value_type数据:m.insert(map<int, int>::value_type(1, ,));
  (3).用数组方式插入数据:m[1] = 1;
  ps:三种有区别:如果已经有元素,最后一个会把原有的数据覆盖,而前两个则不能插入。
  
3.在map中,迭代器指向的是一个pair对象,所以在使用时:it->first,it->second。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值