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的权重计入。

代码

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// 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\n", ans.size());
for (auto it = ans.begin(); it != ans.end(); it++)
printf("%s %d\n", it->first.c_str(), it->second);

return 0;
}

作者:@臭咸鱼

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

欢迎讨论和交流!