1034. Head of a Gang

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 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

基本思路

本题是连通分支算法的一个变种, 不但需要找到连通分支,还要找到该连通分支中度最大的,我采用的方法是每次dfs的时候将本次dfs搜索到的点加入一个vector中,dfs结束,搜索该vector中度最大的节点,但是不要忘了用完以后需要清除vector,否则会重复搜索。

关于名字与节点编码的映射:

本题使用了两个map, 一个用于名字-编码的映射, 一个用于编码-名字映射,若name字段大于3个字符, 可以节省很大的空间,不过就这题而言,开一个26 * 26 * 26的数组未尝不可,也省去了hash的成本,具体的没有尝试过,不知道能不能AC
此题源码如下:

#include <iostream>
#include <vector>
#include <string.h>
#include <string>
#include <algorithm>
#include <map>

#define M 26 * 26 * 26
using namespace std;

typedef struct
{
    int v;
    int w;
} Edge;

typedef struct
{
    string name;
    int cnt;
}Res;

int cmp(Res r1, Res r2)
{
    return r1.name < r2.name;
}
vector< vector<Edge> > edge;
vector<Res> res;
map<int, string> i_s; //编码-名字映射
map<string, int> s_i; //名字-编码映射

int idx = 1;
int N, th;
int weight[M];

void init()
{
    cin >> N >> th;
    edge.resize(M);
    memset(weight, 0, sizeof(weight));
    //邻接链表初始化
    while(N--)
    {
        int time;
        string begin, end;
        cin >> begin >> end >> time;
        if(s_i[begin] == 0)
        {
            i_s[idx] = begin;
            s_i[begin] = idx++;
        }
        if(s_i[end] == 0)
        {
            i_s[idx] = end;
            s_i[end] = idx++;
        }
        int u = s_i[begin];
        int v = s_i[end];

        Edge e;
        e.v = v;
        e.w = time;
        edge[u].push_back(e);
        weight[u] += time;//计算度
        weight[v] += time;
    }
}

int vst[M];
vector<int> sear;

int dfs(int v)
{
    if(vst[v])
        return 0;

    vst[v] = 1;

    sear.push_back(v); //这里把本次搜索到的点加入vector
    int sum = 0;
    for(int i = 0; i < edge[v].size(); i++)
    {
        sum += edge[v][i].w;
        sum += dfs(edge[v][i].v);
    }
    return sum;
}

int main()
{
    init();
    memset(vst, 0, sizeof(vst));
    for(int i = 1; i < idx; i++)
    {
        int t = dfs(i); //dfs

        if(t > th && sear.size() > 2)
        {
            int max = -1;
            int id = 0;
            for(int j = 0; j < sear.size(); j++)
            {
                //搜索最大值
                if(weight[sear[j]] > max)
                {
                    max = weight[sear[j]];
                    id = sear[j];
                }
            }
            Res r;
            r.name = i_s[id];
            r.cnt = sear.size();
            res.push_back(r);   //这个不能忘记
        }
        sear.clear();
    }

    sort(res.begin(), res.end(), cmp);
    //结果输出
    cout << res.size() << endl;
    if(res.size() > 0)
    {
        for(int i = 0; i< res.size(); i++)
        {
            cout << res[i].name << " " << res[i].cnt << endl;
        }
    }
    return 0;
}

posted on   Prince1994  阅读(145)  评论(0编辑  收藏  举报

编辑推荐:
· 用 .NET NativeAOT 构建完全 distroless 的静态链接应用
· 为什么构造函数需要尽可能的简单
· 探秘 MySQL 索引底层原理,解锁数据库优化的关键密码(下)
· 大模型 Token 究竟是啥:图解大模型Token
· 35岁程序员的中年求职记:四次碰壁后的深度反思
阅读排行:
· 基于Docker+DeepSeek+Dify :搭建企业级本地私有化知识库超详细教程
· 电商平台中订单未支付过期如何实现自动关单?
· 用 .NET NativeAOT 构建完全 distroless 的静态链接应用
· 上周热点回顾(3.31-4.6)
· 爆肝 1 周,为我的白板工具支持了 mermaid 流程图,为 ai 生成流程图铺平道路

导航

< 2025年4月 >
30 31 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 1 2 3
4 5 6 7 8 9 10
点击右上角即可分享
微信分享提示