程序设计基础23 图的深度优先搜索

1034 Head of a Gang (30 分)

One way that the police finds the head of a gang is to check people's phone calls. If there is a phone call between A and B, we say that A and B is related. The weight of a relation is defined to be the total time length of all the phone calls made between the two persons. A "Gang" is a cluster of more than 2 persons who are related to each other with total relation weight being greater than a given threthold K. In each gang, the one with maximum total weight is the head. Now given a list of phone calls, you are supposed to find the gangs and the heads.

Input Specification:

Each input file contains one test case. For each case, the first line contains two positive numbers N and K (both less than or equal to 1000), the number of phone calls and the weight threthold, respectively. Then N lines follow, each in the following format:

Name1 Name2 Time

where Name1 and Name2 are the names of people at the two ends of the call, and Time is the length of the call. A name is a string of three capital letters chosen from A-Z. A time length is a positive integer which is no more than 1000 minutes.

Output Specification:

For each test case, first print in a line the total number of gangs. Then for each gang, print in a line the name of the head and the total number of the members. It is guaranteed that the head is unique for each gang. The output must be sorted according to the alphabetical order of the names of the heads.

Sample Input 1:

8 59
AAA BBB 10
BBB AAA 20
AAA CCC 40
DDD EEE 5
EEE DDD 70
FFF GGG 30
GGG HHH 20
HHH FFF 10

Sample Output 1:

2
AAA 3
GGG 3

Sample Input 2:

8 70
AAA BBB 10
BBB AAA 20
AAA CCC 40
DDD EEE 5
EEE DDD 70
FFF GGG 30
GGG HHH 20
HHH FFF 10

Sample Output 2:

0

一,思路

    先要做的是对人名进行编号,即构造一个int_to_str的map,然后就是解决无向图来回都有权值的问题,解决方法就是构建一个weight[]数组,下标即是人名的编号,在输入的时候对于一组的两个人名同时进行weight的相加,然后在遍历到邻接矩阵时出现两个中的其一时,把邻接矩阵的权值归为0,然后把返回来的对称的位置也归为0,防止返回。  

    对人名编号代码:

int charge(string str) {
	if (str_to_int.find(str) != str_to_int.end()) {
		return str_to_int[str];
	}
	else {
		int_to_str[NumPersons] = str;
		str_to_int[str] = NumPersons;
		return NumPersons++;
	}
}

    在深度搜索的时候需要求三个变量,head(当前遍历到的通话时间最长的那个),nowPerson,nowWeight,并且这三者都要引用,因为dfs完一个结点时,需要利用第三个变量。

二,代码

#include<iostream>
#include<string>
#include<map>
using namespace std;
const int max_n = 2100;
int NumPersons = 0;
int N = 0;
int	K = 0;
int weight[max_n] = { 0 };
bool vis[max_n] = { false };
int G[max_n][max_n] = { 0 };
map<string, int> str_to_int;
map<int, string> int_to_str;
map<string, int> Gang;
int charge(string str) {
	if (str_to_int.find(str) != str_to_int.end()) {
		return str_to_int[str];
	}
	else {
		int_to_str[NumPersons] = str;
		str_to_int[str] = NumPersons;
		return NumPersons++;
	}
}
void dfs(int nowVisit, int &head, int &nowPersons, int &nowWeight) {
	nowPersons++;
	vis[nowVisit] = true;
	if (weight[nowVisit] > weight[head]) {
		head = nowVisit;
	}
	for (int i = 0; i < NumPersons; i++) {
		if (G[nowVisit][i] > 0) {
			nowWeight += G[nowVisit][i];
			G[i][nowVisit] = G[nowVisit][i] = 0;
			if (vis[i] == false) {
				dfs(i, head, nowPersons, nowWeight);
			}
		}
	}
}
void dfs_travels() {
	int nowVisit = 0;
	int nowPersons = 0, nowWeight = 0;
	int head = 0;
	for (int i = 0; i < NumPersons; i++) {
		if (vis[i] == false) {
			nowPersons = 0, nowWeight = 0; head = i;
			dfs(i, head, nowPersons, nowWeight);
			if (nowPersons> 2 && nowWeight > K) {
				Gang[int_to_str[head]] = nowPersons;
			}
		}
	}
}
int main() {
	string str1, str2;
	int Time = 0;
	int id1 = 0, id2 = 0;
	cin >> N >> K;
	for (int i = 0; i < N; i++) {
		cin >> str1 >> str2 >> Time;
		id1 = charge(str1);
		id2 = charge(str2);
		weight[id1] += Time;
		weight[id2] += Time;
		G[id1][id2] += Time;
		G[id2][id1] += Time;
	}
	dfs_travels();
	cout << Gang.size() << endl;
	map<string, int>::iterator it;
	for (it = Gang.begin(); it != Gang.end(); it++) {
		cout << it->first << " " << it->second << endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq2285580599/article/details/82801372