PAT甲级1034Head of a Gang

题目链接

https://pintia.cn/problem-sets/994805342720868352/problems/994805456881434624

题解

题目要求

  • 背景

    A和B打电话,则A和B有关系,A和B关系的权重为他们间通话的总时长。

    一个帮派由2个人以上组成,他们关系的总权重超过K。

    帮派中和别人关系的总权重最大的人就是头目。现给出多个通话,请找出头目。

  • 输入

    • N:正整数,不超过1000,通话的数量
    • K:正整数,不超过1000,权重阈值
    • N个通话
  • 输出

    • 帮派的数量
    • 每个帮派的头目和成员数量(按头目名称的字典序输出)

解题思路

  • 通过map保存名字和索引的关系。

  • 一个帮派就是一个连通分量

  • 通过DFS求有多少个连通分量,通过成员数量和总权重进行筛选,最终输出其结点数和头目

  • 题目有个地方很奇怪?要把题目理解对了

    In each gang, the one with maximum total weight is the head. 这句话指出在每个帮派中,总权重最大的人就是头目。

    我起初理解为应在这个帮派之内求每个人的权重(如果A属于某帮派而B不属于这个帮派,那计算A的总权重时,则不应该将A和B的权重包含在内)。但题目的意思是在所有人范围内计算总权重,即使帮派里不包含B,计算A的总权重时也要将A和B的权重计入。

代码

// Problem: PAT Advanced 1034
// URL: https://pintia.cn/problem-sets/994805342720868352/problems/994805456881434624
// Tags: 图 连通分量 map DFS

#include <iostream>
#include <string>
#include <map>
using namespace std;

map<string, int> sti;
map<int, string> its;
map<string, int> ans;
const int MAXN = 2001; // 最多1000个通话,最多就有2000个人
int id = 1;
int e[MAXN][MAXN];
int weight[MAXN];
bool visited[MAXN];

void dfs(int u, int& head, int& totalWeight, int& memberCount){
    visited[u] = true;
    memberCount += 1;
    if (weight[u] > weight[head]){
        head = u;
    }
    for (int v = 1; v < id; v++){
        if (e[u][v] > 0){
            totalWeight += e[u][v]; // 在所有人范围内计算总权重
            e[u][v] = e[v][u] = 0;
            if (!visited[v])
                dfs(v, head, totalWeight, memberCount);
        }
    }
}

int main()
{
    int n, k;
    scanf("%d %d", &n, &k);

    string s1, s2;
    int t;
    for (int i = 0; i < n; i++){
        cin >> s1 >> s2;
        scanf("%d", &t);
        if (sti[s1] == 0){
            sti[s1] = id;
            its[id] = s1;
            id++;
        }
        if (sti[s2] == 0){
            sti[s2] = id;
            its[id] = s2;
            id++;
        }
        e[sti[s1]][sti[s2]] += t;
        e[sti[s2]][sti[s1]] += t;
        weight[sti[s1]] += t;
        weight[sti[s2]] += t;
    }

    for (int i = 1; i < id; i++){
        if (!visited[i]){
            int head = i, totalWeight = 0, memberCount = 0;
            dfs(i, head, totalWeight, memberCount);
            if (memberCount > 2 && totalWeight > k)
                ans[its[head]] = memberCount;
        }

    }

    printf("%d
", ans.size());
    for (auto it = ans.begin(); it != ans.end(); it++)
        printf("%s %d
", it->first.c_str(), it->second);

    return 0;
}

作者:@臭咸鱼

转载请注明出处:https://www.cnblogs.com/chouxianyu/

欢迎讨论和交流!


原文地址:https://www.cnblogs.com/chouxianyu/p/13735860.html