【1034】Head of a Gang (30 分)

举报
野猪佩奇996 发表于 2022/01/23 23:08:21 2022/01/23
【摘要】 #include<iostream>#include<stdio.h>#include<stdlib.h>#include<math.h>#include<string>#include<algorithm> #include<map>#include...

  
  1. #include<iostream>
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4. #include<math.h>
  5. #include<string>
  6. #include<algorithm>
  7. #include<map>
  8. #include<vector>
  9. #include<queue>
  10. using namespace std;
  11. const int maxn=2010; //总人数
  12. map<int, string> intToString; //编号-》姓名
  13. map<string,int> stringToInt; //姓名-》编号
  14. map<string,int> Gang; //head->人数
  15. int G[maxn][maxn]={0};
  16. int weight[maxn]={0}; //邻接矩阵G、点权weight
  17. int n,k,numPerson=0; //边数n、下限k及总人数numPerson
  18. bool vis[maxn]={false}; //标记是否被访问
  19. //DFS函数访问单个连通块,nowVisit为当前访问的标号
  20. //head为头目,numMember为成员编号,totalValue为连通块的总边权
  21. void DFS(int nowVisit,int& head, int& numMember,int& totalValue){
  22. numMember++;//成员人数加1
  23. vis[nowVisit]=true; //标记nowVisit已访问
  24. if(weight[nowVisit]>weight[head]){
  25. head=nowVisit; //当前访问结点的点权大于头目的点权,则更新头目
  26. }
  27. for(int i=0;i<numPerson;i++){ //枚举所有人
  28. if(G[nowVisit][i]>0){ //如果从nowVisit能到达i
  29. totalValue += G[i][nowVisit] ; //连通块的总边权增加该边权
  30. G[nowVisit][i]=G[i][nowVisit]=0; //删除这条边,防止回头
  31. if(vis[i] == false){ //如果i未被访问,则递归访问i
  32. DFS(i,head,numMember,totalValue);
  33. }
  34. }
  35. }
  36. }
  37. //DFSTrave函数遍历整个图,获取每个连通块的信息
  38. void DFSTrave(){
  39. for(int i=0;i<numPerson;i++){ //枚举所有人
  40. if(vis[i]==false){ //如果i未被访问
  41. int head=i,numMember=0,totalValue=0; //头目、成员数、总边权
  42. DFS(i,head,numMember,totalValue); //遍历i所在的连通块
  43. //如果成员数大于2且总边权大于k
  44. if(numMember>2 && totalValue >k){
  45. //head的人数为numMember
  46. Gang[intToString[head] ]=numMember;
  47. }
  48. }
  49. }
  50. }
  51. //change函数返回姓名str对应的编号
  52. int change(string str){
  53. if(stringToInt.find(str) != stringToInt.end()){ //如果str已经出现过
  54. return stringToInt[str]; //返回编号
  55. }else{
  56. stringToInt[str]=numPerson; //str的编号为numPerson
  57. intToString[numPerson]=str; //numPerson对应str
  58. return numPerson++; //总人数加1
  59. }
  60. }
  61. int main(){
  62. int w;
  63. string str1,str2;
  64. cin >> n>>k;
  65. for(int i=0; i<n; i++){
  66. cin >> str1>>str2>>w; //输入边的两个端点和点权
  67. int id1=change(str1); //将str1转换为编号id1
  68. int id2=change(str2); //将str2转换为编号id2
  69. weight[id1]+=w; //id1的点权增加w
  70. weight[id2]+=w; //id2的点权增加w
  71. G[id1][id2]+=w; //边id1-》id2的边权增加w
  72. G[id2][id1]+=w; //边id2-》id1的边权增加w
  73. }
  74. DFSTrave(); //遍历整个图的所有连通块,获取Gang的信息
  75. cout <<Gang.size()<< endl; //Gang的个数
  76. map<string,int>::iterator it;
  77. for(it=Gang.begin(); it!=Gang.end();it++){ //遍历所有Gang
  78. cout << it->first << " "<< it->second<<endl; //输出信息
  79. }
  80. system("pause");
  81. return 0;
  82. }

 

文章来源: andyguo.blog.csdn.net,作者:山顶夕景,版权归原作者所有,如需转载,请联系作者。

原文链接:andyguo.blog.csdn.net/article/details/100022367

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。