PAT A1034团伙头目

题意:

给出N条通话记录,这些通话将他们分为若干组。每个组的总边权为该组内的所有通话的长度之和,每个人的点权设为该人参加的通话长度之和。给定阀值K,超过阀值且大于二人的组被视为犯罪团伙,而组内点权最大的人被视为头目,要求输出团伙个数和每个团伙的头目,以及成员个数。

思路:

  1. 首先是姓名字符串和编号的对应关系:map<string,int>
  2. 求某点相连的边权之和
  3. 进行图的遍历,获取每个连通块的头目、成员个数、总边权。
  4. 如果总边权>K,且人数>2,则记录为一个犯罪团伙

代码:

#include<iostream>
#include<map>
using namespace std;
map<string,int> stringToint;
map<int, string> intTostring;
map<string, int> ans;
int idNumber=1,k;
int stoifunc(string s){
	if(stringToint[s]==0){
		stringToint[s]=idNumber;
		intTostring[idNumber]=s;
		return idNumber++;
	}else{
		return stringToint[s];
	}
} 
int G[2010][2010],weight[2010];
bool vis[2010];
void dfs(int u,int &head,int &numMember,int &totalweight){
	vis[u]=true;
	numMember++;
	if(weight[u]>weight[head]){
		head=u;
	}
	for(int v=1;v<idNumber;v++){
		if(G[u][v]>0){
			totalweight+=G[u][v];
			G[u][v]=G[v][u]=0;
			if(vis[v]==false){
				dfs(v,head,numMember,totalweight);
			}
		}
	}
}
void dfsTrave(){
	for(int i=1;i<idNumber;i++){
		if(vis[i]==false){
			int head=i,numMember=0,totalweight=0;
			dfs(i,head,numMember,totalweight);
			if(numMember>2&&totalweight>k){
				ans[intTostring[head]]=numMember;
			}
		}
	}
}
int main(){
	int n,w;
	cin >> n >> k;
	string s1,s2;
	for(int i=0;i<n;i++){
		cin >> s1 >> s2 >> w;
		int id1=stoifunc(s1);
		int id2=stoifunc(s2);
		weight[id1]+=w;
		weight[id2]+=w;
		G[id1][id2]+=w;
		G[id2][id1]+=w;
	}
	dfsTrave();
	cout << ans.size() << endl;
	for(auto it=ans.begin();it!=ans.end();it++){
		cout<<  it->first << " " << it->second <<endl;  
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值