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
题目大意:给出一些通话记录,每条记录的格式为通话者的名字识和他们间通话的时长,若两个人有通过话则说明他们是有关联的。有关联的人(间接产生关联也行)可以组成一个集合,题目要求找出所有满足下面的条件的集合。
条件一:这个集合内人的个数大于2
条件二:这个集合内的人的通话时间的总数大于给定值K(注:若A和B通话10分钟,则通话总数为10,不是20)
最后输出满足上述要求的每个集合中的和别人通话时间最长的人和他所在的集合包含的成员的个数。
两大坑:
- 读入通话信息数据时,同样的两个人间可能存在多次通话记录
- 题目中给出的N是指的边的个数,不是节点的个数!不注意这个问题会出现段错误
#include <bits/stdc++.h>
using namespace std;
typedef pair<string,int> P;
const int maxn = 2005;
int G[maxn][maxn];
int mark[maxn];
vector<int> tempGroup;
vector<vector<int> > groups;
int id = 0;
void dfs(int i){
mark[i] = 1;
tempGroup.push_back(i);
for(int j = 0;j < id; j++){
if(G[i][j] > 0 && mark[j] == 0){
dfs(j);
}
}
}
int main(int argc, char const *argv[])
{
int n,K,T;
cin >> n >> K;
string name1,name2;
map<string,int> name2id;
map<int,string> id2name;
memset(G, 0, sizeof(G));
memset(mark, 0, sizeof(mark));
for(int i = 0;i < n; i++){
cin >> name1 >> name2 >> T;
if(name2id.count(name1) == 0){
name2id[name1] = id;
id2name[id] = name1;
id++;
}
if(name2id.count(name2) == 0){
name2id[name2] = id;
id2name[id] = name2;
id++;
}
G[name2id[name1]][name2id[name2]] += T;
}
for(int i = 0;i < id; i++){
if(mark[i] == 0){
dfs(i);
groups.push_back(tempGroup);
tempGroup.clear();
}
}
set<P> ans;
for(int i = 0;i < groups.size(); i++){
// 对于每一组,计算本组成员间的通话分钟总数,groupTotal
// 计算每组中和其他组内成员通话分钟数最多的成员 maxi,最大通话数,maxTotal
// 成员和组内成员通话总数 total
int groupTotal = 0, maxi = 0, maxTotal = 0, total;
for(int j = 0;j < groups[i].size(); j++){
total = 0;
for(int k = 0;k < groups[i].size(); k++){
total += G[groups[i][j]][groups[i][k]];
total += G[groups[i][k]][groups[i][j]];
}
if(maxTotal < total){
maxi = groups[i][j];
maxTotal = total;
}
groupTotal += total;
}
if(groupTotal > 2*K && groups[i].size() > 2){ # 注意这里是2*K
ans.insert(make_pair(id2name[maxi], groups[i].size()));
}
}
cout << ans.size() << endl;
for(auto it : ans){
cout << it.first << " " << it.second << endl;
}
return 0;
}
本文介绍了一种利用通话记录数据来识别犯罪团伙的方法,通过分析电话网络中个体之间的联系强度,确定团伙头目及成员,提供了一种有效识别犯罪网络的算法实现。
1153

被折叠的 条评论
为什么被折叠?



