arena 2035

#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};//邻接矩阵,点权weight
int 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人数为numMember
				Gang[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对应的编号为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;
		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;
} 

你可能感兴趣的:(map,邻接矩阵,pat,图的DFS遍历)