A1034 Head of a Gang (30分)

一、技术总结

  1. 这一题是关于图的遍历的,首先拿到题目理解题意,可以发现第一个需要考虑的问题是如何存储的问题。
  2. 然后就是考虑使用哪种遍历方法的问题,这里使用DFS遍历的方法。
  3. 然后还有就是如何存储字符串和编号的问题,使用map<string, int>,进行解决。最后就是关于统计每一个连通分量是否达标,一个是人数,一个是阀值。所以需要重新开辟一个空间来进行记录。也是使用map,用权重最大的字符串,进行对应的人数。
  4. 同时如果使用邻接矩阵,和一个bool数组用于记录结点是否被访问过是常规操作。
  5. 对于DFS函数,需要考虑的就是参数问题,这一题中一个当前结点编号为一个i参数,还有就是head作为记录权值最大的一个作为参数,在一个就是记录人数numMember作为参数,再一个就是totalValue,总权值相加看是否达到阀值。
  6. 其余细节参考代码

二、参考代码

#include<bits/stdc++.h>
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;//边数n,下限k, 总人数numPerson
bool vis[maxn] = {false};//标记是否被访问
//DFS函数访问单个连通块,nowVisit为当前访问的编号
//head为头目,numMember为成员编号,totalValue为连通块的总边权
void DFS(int nowVisit, int& head, int& numMember, int& totalValue){
	numMember++;//成员人数加一
	vis[nowVisit] = true;//标记为已访问
	if(weight[nowVisit] > weight[head]){
		head = nowVisit;
	} 
	for(int i = 0; i < numPerson; i++){
		if(G[nowVisit][i] > 0){
			totalValue += G[nowVisit][i];//连通块的总边权增加该边权 
			G[nowVisit][i] = G[i][nowVisit] = 0;
			if(vis[i] == false){
				DFS(i, head, numMember, totalValue);
			}
		}
	}	
} 
//DFSTrace函数遍历整个图
void DFSTrace(){
	for(int i = 0; i < numPerson; i++){
		if(vis[i] == false){
			int head = i, numMember = 0, totalValue = 0;//头目、成员数、总边权
			DFS(i, head, numMember, totalValue);
			if(numMember > 2 && totalValue > k){
				//head人数为numMember
				Gang[intToString[head]] = numMember; 
			} 
		}
	}
} 
//change函数返回姓名str对应的编号
int change(string str){
	if(stringToInt.find(str) != stringToInt.end()){
		return stringToInt[str];
	}else{
		stringToInt[str] = numPerson;
		intToString[numPerson] = str;
		return numPerson++;
	}
} 
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);
		int id2 = change(str2);
		weight[id1] += w;
		weight[id2] += w;
		G[id1][id2] += w;
		G[id2][id1] += w; 
	}
	DFSTrace();
	cout << Gang.size() << endl;
	for(auto it = Gang.begin(); it != Gang.end(); it++){
		cout << it->first << " " << it->second << endl; 
	}
	return 0;
}
posted @ 2020-02-25 22:47  睿晞  阅读(127)  评论(0编辑  收藏  举报