1034. Head of a Gang

【题意】
        给出一些人互相通话的记录,根据通话关系以及时间找出其中的团伙以及每个团伙的leader

【思路】

        用map存下每个人姓名、通话时间、团伙编号、访问记号以及相互通话的人的关系,通过DFS找到共有几个团伙(即连通分量)。同时再用一个vector记录下每个团伙的总通话时间、成员列表,方便最后找到leader。


#include <iostream>
#include <string>
#include <cstring>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;

typedef struct{
	string name;
	int weight;
	int lable;
	bool visited;
	vector<string> neighbours;
}person;

typedef struct{
	int totalWeight;
	vector<person> numbers;
}gang;

map<string,person> persons;
vector<gang> gangs;

void dfs(string name, int lable){
	persons[name].visited = 1;
	persons[name].lable = lable;
	gangs[lable].totalWeight += persons[name].weight;
	gangs[lable].numbers.push_back(persons[name]);
	for(vector<string>::iterator it=persons[name].neighbours.begin(); it!=persons[name].neighbours.end(); it++){
		if(!persons[(*it)].visited){
			dfs(*it,lable);
		}
	}
}

int main(int argc, char const *argv[])
{
	int n,threshold,id;

	id = 0;
	cin >> n >> threshold;
	for(int i=0; i<n; i++){
		string name[2];
		int timeOfCall;
		cin >> name[0] >> name[1] >> timeOfCall;
		for(int j=0; j<2; j++){
			if(persons.find(name[j])==persons.end()){
				persons[name[j]].name = name[j];
				persons[name[j]].weight = timeOfCall;
				persons[name[j]].visited = 0;
			}
			else{
				persons[name[j]].weight += timeOfCall;
			}
			persons[name[j]].neighbours.push_back(name[1-j]);
		}
	}

	//DFS
	int lable = 0;
	for(map<string,person>::iterator it=persons.begin(); it!=persons.end(); it++){
		if(!(*it).second.visited){
			gang tmp;
			tmp.totalWeight = 0;
			gangs.push_back(tmp);
			dfs((*it).first,lable);
			gangs[lable].totalWeight /= 2;
			lable++;
		}
	}

	vector<string> validGangLeader;
	for(int i=0; i<lable; i++){
		if(gangs[i].totalWeight>threshold && gangs[i].numbers.size()>2){
			int maxWeight = 0;
			string name;
			for(vector<person>::iterator it=gangs[i].numbers.begin(); it!=gangs[i].numbers.end(); it++){
				if((*it).weight>maxWeight){
					maxWeight = (*it).weight;
					name = (*it).name;
				}
			}
			validGangLeader.push_back(name);
		}
	}
	sort(validGangLeader.begin(),validGangLeader.end());
	cout << validGangLeader.size();
	for(int i=0; i<validGangLeader.size(); i++){
		cout << endl << validGangLeader[i] << " " << gangs[persons[validGangLeader[i]].lable].numbers.size();
	}

	system("pause");
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值