题目:https://pintia.cn/problem-sets/994805342720868352/problems/994805456881434624
题意:
给定n条记录(注意不是n个人的记录),两个人之间的关系的权值为这两个人之间所有电话记录的时间之和。
一个连通块的权值为所有关系权值之和。
如果一个连通块节点数大于2,且权值大于给定的k,称这是一个gang,拥有关系权值和最多的人是gang的头。
要求输出gang的数量,每个gang的头,每个gang的人数。按照gang的头的字典序排序。
思路:
bfs求连通块。有几个注意点:
1、给定的是n条记录,$n<=1000$, 这说明人数应该是2000以内而不是1000以内。否则会有段错误
2、每一条记录都要考虑,bfs时不能仅判断这个节点是否被访问,还应该设置边的vis数组。
#include<cstdio>
#include<cstdlib>
#include<map>
#include<set>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
#include<stack>
#include<queue> #define inf 0x7fffffff
using namespace std;
typedef long long LL;
typedef pair<string, string> pr; int n, k;
map<string, int>mp;
map<int, string>revmp;
const int maxn = ;
int g[maxn][maxn];
int tot = ; struct node{
int head;
int mxweight = -;
int num;
}gang[maxn];
int ans = ;
bool vis[maxn];
bool evis[maxn][maxn]; void bfs()
{
for(int i = ; i < tot; i++){
if(!vis[i]){
int weight = ;
queue<int>que;
que.push(i);
vis[i] = true;
//printf("\n%d ", i); while(!que.empty()){
int now = que.front();que.pop();
gang[ans].num++;
int res = ;
for(int j = ; j < tot; j++){
res += g[now][j];
if(!evis[now][j] && g[now][j]){
weight += g[now][j];
evis[now][j] = evis[j][now] = true;
}
if(!vis[j] && g[now][j]){
que.push(j);
vis[j] = true;
}
}
if(res > gang[ans].mxweight){
gang[ans].mxweight = res;
gang[ans].head = now;
}
}
if(weight > k && gang[ans].num > ){
ans++;
}
else{
gang[ans].num = ;
gang[ans].mxweight = -;
gang[ans].head = ;
}
}
}
} bool cmp(node a, node b)
{
return revmp[a.head] < revmp[b.head];
} int main()
{
scanf("%d%d", &n, &k);
for(int i = ; i < n; i++){
string a, b;
int val;
cin>>a>>b>>val; if(mp.find(a) == mp.end()){
revmp[tot] = a;
mp[a] = tot++;
}
if(mp.find(b) == mp.end()){
revmp[tot] = b;
mp[b] = tot++;
}
g[mp[a]][mp[b]] += val;
g[mp[b]][mp[a]] += val;
}
//cout<<tot<<endl;
// for(int i = 0; i < tot; i++){
// for(int j = 0; j < tot; j++){
// printf("%d ", g[i][j]);
// }
// printf("\n");
// }
bfs();
printf("%d\n", ans);
sort(gang, gang + ans, cmp);
for(int i = ; i < ans; i++){
cout<<revmp[gang[i].head]<<" "<<gang[i].num<<endl;
}
return ;
}