1034.Head of a Gang (30)

1034.Head of a Gang (30)

pat-al-1034

2017-02-04

  • 图的遍历,连通分量,dfs
  • 对于每一个连通分量,要求其head和包含的成员个数,以及该gang的总权值
  • 套路:用map来映射名称和序号、visited、边e、节点权重weight
  • 练习了用迭代器输出map的内容
  • 坑见注释
/**
 * pat-al-1034
 * 2017-02-04
 * Cpp version
 * Author: fengLian_s
 */
#include<stdio.h>
#include<iostream>
#include<map>
#include<string>
#define MAX 2003//坑……我还以为是1000,导致段错误
using namespace std;
int k;
int maxNumberOfPeople = 1;
int visited[MAX], weight[MAX], e[MAX][MAX];
map<string, int> str2int;
map<int, string> int2str;
map<string, int> result;
int string2int(string s)
{
  if(str2int[s] == 0)//还未放入映射中
  {
    str2int[s] = maxNumberOfPeople;
    int2str[maxNumberOfPeople] = s;
    //cout << s << ": " << maxNumberOfPeople << endl;
    return maxNumberOfPeople++;
  }
  else
    return str2int[s];
}
void dfs(int u, int &head, int &numberOfMember, int &totalWeight)
{
  visited[u] = 1;
  numberOfMember++;
  if(weight[u] > weight[head])
    head = u;
  for(int v = 1;v < maxNumberOfPeople;v++)
  {
    if(e[u][v] != 0)//坑:和下面的visited必须要分开判断,此处判断的是是否有边没有加入总权重
    {
      totalWeight += e[u][v];
      //printf("e[%d][%d] = %d\n", u, v, e[u][v]);
      e[u][v] = e[v][u] = 0;//坑,一条路只能加一遍
      if(visited[v] == 0)//坑:visited判断的时候是否继续深搜
        dfs(v, head, numberOfMember, totalWeight);
    }
  }
}
int main()
{
  int n;
  scanf("%d%d", &n, &k);
  for(int i = 0;i < n;i++)
  {
    string s1, s2;
    int w;
    cin >> s1 >> s2 >> w;
    int id1, id2;
    id1 = string2int(s1);
    id2 = string2int(s2);
    weight[id1] += w;
    weight[id2] += w;
    e[id1][id2] += w;
    e[id2][id1] += w;//坑,不用+=的话会被新的权值覆盖
  }
  //solve:
  for(int i = 1;i < maxNumberOfPeople;i++)
  {
    if(visited[i] == 0)
    {
      int head = i, totalWeight = 0, numberOfMember = 0;
      dfs(i, head, numberOfMember, totalWeight);
      //cout << "head = " << head << ", numberOfMember = " << numberOfMember << ", totalWeight = " << totalWeight << endl;
      if(numberOfMember > 2 && totalWeight > k)
        result[int2str[head]] = numberOfMember;
    }
  }
  //output:
  printf("%lu\n", result.size());
  for(map<string, int>::iterator it = result.begin();it != result.end();it++)
    cout << it->first << " " << it->second << endl;
  return 0;
}

-FIN-

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值