arena 2035

来源:互联网 发布:小米6怎么样知乎 编辑:程序博客网 时间:2024/04/26 05:43
#include<cstdio>#include<string>#include<map>using namespace std;const int maxn=2010;//总人数const int INF=1000000000;//无穷大map<int,string> intToString;//编号-姓名map<string,int> stringToInt;//姓名->编号map<string,int> Gang;///head->人数int G[maxn][maxn]={0},weight[maxn]={0};//邻接矩阵,点权weightint n,k,numPerson=0;//边数,下限k,总人数numPerson bool vis[maxn]={false};//标记是否被访问  //DFS函数访问单个连通块,目的是获取成员个数,总边权,每个连通块的头目,即连通块内权最大的结点。//nowVisit为当前访问的编号。head 为头目,numMember为成员个数、totalValue为连通块的总边权,均为引用。 void DFS(int nowlist,int &head,int numMember,int& totalValue){numMember++;//成员人数增加1 vis[nowVisit]=true;//标记nowVisit为已经访问if(weight[nowVisit]>weight[head]){//当前范文结点的点权大于头目的点权则更新头目head=nowlist; }for(int i=0;i<numPerson;i++){//枚举所有人 if(G[nowVisit][i]>0){//如果从nowVisit能到达i totalValue+=G[nowVisit][i];//连通块的总边权增加该边权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所在的连通块//到这里就遍历结束了 if(numMember>2&&totalValue>k){//遍历结束后,成员数大于2且总边权大于k //head人数为numMemberGang[intToString[head]]=numMember;//以这个head为头目的帮派的总人数,注意这里用到了Map } }}}//change函数返回姓名str对应的编号int change(string str){if(stringToInt.find(str)!=stringToInt.end()){//如果str已经出现过 return stringToInt(str);//返回编号,不懂 }else{stringToInt[str]=numPerson;//str对应的编号为numPersonintToString[numPerson]=str;//numPerson对应strreturn 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转化为编号Id1int id2=change(str2);//将str2转化为编号id2weight[id1]+=w;weight[id2]+=w;G[id1][id2]+=w;G[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;//输出信息 } return 0;} 

0 0
原创粉丝点击