PAT甲级1034 Head of a Gang【bfs】

题目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 }

 

posted @ 2019-04-05 14:46  wyboooo  阅读(284)  评论(0编辑  收藏  举报