PAT A-1034 Head of a Gang

本题未通过所有测试案例(20/30),希望有大佬能解答

本题链接:1034 Head of a Gang - PAT (Advanced Level) Practice (pintia.cn)

题意:

    在很多个小团体中,找到符合条件(即总weight > k,且人数 > 2)的团队个数,输出团队头头(即weight最大的人),及该团队成员

思路:

  首先用map<string,node>创建str(其中node包含index和weight),将每个人的名字与编号和权重连接起来,这样在创建邻接表的时候只需要存入个人编号,dfs时候更方便。然后通过dfs,用一个vector数组每一个团队的所有成员,如果该团队符合要求,找到里面的头头存入head数组中,最后将head数组输出。

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

struct node {
	int index;
	int weight;
};

const int N = 1010;
int n, k;
vector < vector <int> > mp;
map<string, node> str; //将0123与名字的对应
map<int, int> weigh;//记录每个点的出度

bool vis[1010];
int res = 0;
vector<int> gang;//这是一群
vector<int> head;//记录头头
vector<int> member;//记录对应的人数

//查找图中是否存在该点
bool charge(int father,int son) {
	for (int i = 0; i < mp[father].size(); i++) {
		if (mp[father][i] == son) {
			return true;
		}
	}
	return false;
}

//在str中,通过index求其weight
int findW(int index){
	map<string, node>::iterator it = str.begin();
	while (true) {
		if (it->second.index == index) {
			return it->second.weight;
		}
		it++;
	}
}

string findS(int index) {
	map<string, node>::iterator it = str.begin();
	while (true) {
		if (it->second.index == index) {
			return it->first;
		}
		it++;
	}
}

void dfs(int index) {
	gang.push_back(index);
	vis[index] = true;
	/*int nowW = mp[index][0].weight;
	res++;

	int maxH = mp[index][0].weight;
	string hName = mp[index][0].name;
	for (int i = 0; i < mp[index].size(); i++) {
		vis[find(mp[index][i].name)] = true;
		nowW += mp[index][i].weight;
		if (mp[index][i].weight > maxH) {
			maxH = mp[index][i].weight;
			hName = mp[index][i].name;
		}
	}

	head.push_back(newNode(hName, maxH));*/

	for (int i = 0; i < mp[index].size(); i++) {
		if (!vis[mp[index][i]]) 
		dfs(mp[index][i]);
	}
}

void init() {
	for (int i = 0; i < N; i++) {
		vis[i] = false;
	}

	for (int i = 0; i < 2 * N; i++) {
		vector<int> a;
		mp.push_back(a);
	}
}


//ab有关系指两人打过电话,打电话总时间为权重
//gang三个人以上相关,且总权重大于给的K值
//head是gang里权重最大的人
int main() {
	int num = 0;//记录共有几一个人
	cin >> n >> k;

	init();
	
	for (int i = 0; i < n; i++) {
		string a, b;
		int t;
		cin >> a >> b >> t;
		//处理str
		map<string, node>::iterator it = str.find(a);
		if (it == str.end()) {
			node now;
			now.index = num;
			num++;
			now.weight = t;
			str[a] = now;
		}
		else {
			it->second.weight += t;
		}
		
		it =  str.find(b);
		if (it == str.end()) {
			node now;
			now.index = num;
			num++;
			now.weight = t;
			str[b] = now;
		}
		else {
			it->second.weight += t;
		}
  
		//加入图
		if (!charge(str.find(a)->second.index, str.find(b)->second.index)) {
			mp[str.find(a)->second.index].push_back(str.find(b)->second.index);
		}
		if(!charge(str.find(b)->second.index, str.find(a)->second.index)) {
			mp[str.find(b)->second.index].push_back(str.find(a)->second.index);
		}
		
	}

	for (int i = 0; i <= num; i++) {
		if (!vis[i]) {
			dfs(i);
			if (gang.size() > 2) {
				int maxI = 0;
				int max = 0;
				int sum = 0;
				for (int i = 0; i < gang.size(); i++) {
					sum += findW(gang[i]);
					if (findW(gang[i]) > max) {
						max = findW(gang[i]);
						maxI = gang[i];
					}
				}

				if (sum/2 > k) {
					res++;
					head.push_back(maxI);
					member.push_back(gang.size());
				}
			}
			gang.clear();
		}
	}

	cout << res << endl;
	for (int i = 0; i < head.size(); i++) {
		cout << findS(head[i]) << " " << member[i] << endl;
	}
	
	return 0;
}

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值