PAT A1034 Head of a Gang
思路:通过邻接矩阵构建帮派图,通过DFS确定不同的连通分量来确定帮派个数以及人数。
注意给出的图结构为无向图,为结点添加完权重之后,由最大权重确定帮派牢大。
整个帮派的阈值由边权确定,即每条边只使用一次,使用后将边权置0,防止重复使用边。
注意题目给出最大的n为1000,但考虑到通话是双方的,因此maxn应该大于2000。
#include<iostream>
#include<cstdio>
#include<string>
#include<map>
using namespace std;
const int maxn = 2010;
map<string, int> Str2Int;
map<int, string> Int2Str;
map<string, int> Gang;
bool visit[maxn];
int G[maxn][maxn], weight[maxn];
int N, K, num;
int transform(string s) {
if(Str2Int.find(s) != Str2Int.end())
return Str2Int[s];
Str2Int[s] = ++num;
Int2Str[num] = s;
return num;
}
void DFS(int nowVisit, int& head, int& numMember, int& totalWeight) {
numMember++;
visit[nowVisit] = true;
if(weight[nowVisit] > weight[head])
head = nowVisit;
for(int i = 1; i <= num; i++)
if(G[nowVisit][i] > 0) {
totalWeight += G[nowVisit][i];
G[nowVisit][i] = G[i][nowVisit] = 0;
if(!visit[i]) DFS(i, head, numMember, totalWeight);
}
}
int main() {
cin >> N >> K;
string s1, s2;
int w;
for(int i = 0; i < N; i++) {
cin >> s1 >> s2 >> w;
int id1 = transform(s1);
int id2 = transform(s2);
G[id1][id2] += w;
G[id2][id1] += w;
weight[id1] += w;
weight[id2] += w;
}
int head, numMember, totalWeight;
for(int i = 1; i <= num; i++)
if(!visit[i]) {
head = i, numMember = 0, totalWeight = 0;
DFS(i, head, numMember, totalWeight);
if(numMember > 2 && totalWeight > K)
Gang[Int2Str[head]] = numMember;
}
cout << Gang.size() << endl;
for(auto &res : Gang)
cout << res.first << " " << res.second << endl;
return 0;
}