【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...

      #include<iostream>
      #include<stdio.h>
      #include<stdlib.h>
      #include<math.h>
      #include<string>
      #include<algorithm> 
      #include<map>
      #include<vector>
      #include<queue> 
      using namespace std;
      const int maxn=2010; //总人数
      map<int, string> intToString; //编号-》姓名
      map<string,int> stringToInt;  //姓名-》编号
      map<string,int> Gang;  //head->人数
      int G[maxn][maxn]={0};
      int weight[maxn]={0};  //邻接矩阵G、点权weight
      int n,k,numPerson=0; //边数n、下限k及总人数numPerson
      bool vis[maxn]={false};  //标记是否被访问
      //DFS函数访问单个连通块,nowVisit为当前访问的标号
      //head为头目,numMember为成员编号,totalValue为连通块的总边权
      void DFS(int nowVisit,int& head, int& numMember,int& totalValue){
      	numMember++;//成员人数加1
      	vis[nowVisit]=true; //标记nowVisit已访问
     	if(weight[nowVisit]>weight[head]){
      		head=nowVisit; //当前访问结点的点权大于头目的点权,则更新头目
      	}
     	for(int i=0;i<numPerson;i++){ //枚举所有人
     		if(G[nowVisit][i]>0){  //如果从nowVisit能到达i
      			totalValue += G[i][nowVisit] ; //连通块的总边权增加该边权
      			G[nowVisit][i]=G[i][nowVisit]=0;  //删除这条边,防止回头
     			if(vis[i] == false){ //如果i未被访问,则递归访问i
     				DFS(i,head,numMember,totalValue);
      			}
      		}
      	}
      }
      //DFSTrave函数遍历整个图,获取每个连通块的信息
      void DFSTrave(){
     	for(int i=0;i<numPerson;i++){ //枚举所有人
     		if(vis[i]==false){  //如果i未被访问
     			int head=i,numMember=0,totalValue=0; //头目、成员数、总边权
     			DFS(i,head,numMember,totalValue); //遍历i所在的连通块
     			//如果成员数大于2且总边权大于k
     			if(numMember>2 && totalValue >k){
     				//head的人数为numMember
      				Gang[intToString[head] ]=numMember;
      			}
      		}
      	}
      }
      //change函数返回姓名str对应的编号
      int change(string str){
     	if(stringToInt.find(str) != stringToInt.end()){ //如果str已经出现过
     		return stringToInt[str]; //返回编号
      	}else{
      		stringToInt[str]=numPerson; //str的编号为numPerson
      		intToString[numPerson]=str; //numPerson对应str
     		return numPerson++;  //总人数加1
      	}
      }
      int main(){
     	int w;
      	string str1,str2;
      	cin >> n>>k;
     	for(int i=0; i<n; i++){
      		cin >> str1>>str2>>w; //输入边的两个端点和点权
     		int id1=change(str1);  //将str1转换为编号id1
     		int id2=change(str2); //将str2转换为编号id2
      		weight[id1]+=w;  //id1的点权增加w
      		weight[id2]+=w;  //id2的点权增加w
      		G[id1][id2]+=w;  //边id1-》id2的边权增加w
      		G[id2][id1]+=w; //边id2-》id1的边权增加w
      	}
     	DFSTrave();  //遍历整个图的所有连通块,获取Gang的信息
      	cout <<Gang.size()<< endl; //Gang的个数
      	map<string,int>::iterator it;
     	for(it=Gang.begin(); it!=Gang.end();it++){ //遍历所有Gang
      		cout << it->first  << " "<< it->second<<endl; //输出信息
      	}
     	system("pause");
         return 0;
      }
  
 

 

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

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

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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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