题目: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数组。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<map> 4 #include<set> 5 #include<iostream> 6 #include<cstring> 7 #include<algorithm> 8 #include<vector> 9 #include<cmath> 10 #include<stack> 11 #include<queue> 12 13 #define inf 0x7fffffff 14 using namespace std; 15 typedef long long LL; 16 typedef pair<string, string> pr; 17 18 int n, k; 19 map<string, int>mp; 20 map<int, string>revmp; 21 const int maxn = 2005; 22 int g[maxn][maxn]; 23 int tot = 0; 24 25 struct node{ 26 int head; 27 int mxweight = -1; 28 int num; 29 }gang[maxn]; 30 int ans = 0; 31 bool vis[maxn]; 32 bool evis[maxn][maxn]; 33 34 void bfs() 35 { 36 for(int i = 0; i < tot; i++){ 37 if(!vis[i]){ 38 int weight = 0; 39 queue<int>que; 40 que.push(i); 41 vis[i] = true; 42 //printf("\n%d ", i); 43 44 while(!que.empty()){ 45 int now = que.front();que.pop(); 46 gang[ans].num++; 47 int res = 0; 48 for(int j = 0; j < tot; j++){ 49 res += g[now][j]; 50 if(!evis[now][j] && g[now][j]){ 51 weight += g[now][j]; 52 evis[now][j] = evis[j][now] = true; 53 } 54 if(!vis[j] && g[now][j]){ 55 que.push(j); 56 vis[j] = true; 57 } 58 } 59 if(res > gang[ans].mxweight){ 60 gang[ans].mxweight = res; 61 gang[ans].head = now; 62 } 63 } 64 if(weight > k && gang[ans].num > 2){ 65 ans++; 66 } 67 else{ 68 gang[ans].num = 0; 69 gang[ans].mxweight = -1; 70 gang[ans].head = 0; 71 } 72 } 73 } 74 } 75 76 77 bool cmp(node a, node b) 78 { 79 return revmp[a.head] < revmp[b.head]; 80 } 81 82 int main() 83 { 84 scanf("%d%d", &n, &k); 85 for(int i = 0; i < n; i++){ 86 string a, b; 87 int val; 88 cin>>a>>b>>val; 89 90 if(mp.find(a) == mp.end()){ 91 revmp[tot] = a; 92 mp[a] = tot++; 93 } 94 if(mp.find(b) == mp.end()){ 95 revmp[tot] = b; 96 mp[b] = tot++; 97 } 98 g[mp[a]][mp[b]] += val; 99 g[mp[b]][mp[a]] += val; 100 } 101 //cout<<tot<<endl; 102 // for(int i = 0; i < tot; i++){ 103 // for(int j = 0; j < tot; j++){ 104 // printf("%d ", g[i][j]); 105 // } 106 // printf("\n"); 107 // } 108 bfs(); 109 printf("%d\n", ans); 110 sort(gang, gang + ans, cmp); 111 for(int i = 0; i < ans; i++){ 112 cout<<revmp[gang[i].head]<<" "<<gang[i].num<<endl; 113 } 114 return 0; 115 }