PAT1034. Head of a Gang

本文介绍了一个使用C++实现的图遍历算法,通过广度优先搜索(BFS)来寻找满足特定条件的节点集合。算法处理了一个包含多个节点的图,每个节点代表一个人名,并通过边连接表示这些人之间的关系。目标是在不超过给定时间限制的情况下,找到最大的节点集合,同时确保集合中任意两个节点间的路径长度大于设定阈值。文章详细展示了如何构建图、进行广度优先搜索以及处理搜索结果的全过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <functional>
#include <string>
#include <queue>
using namespace std;

int N;
int K;
vector<string> names;
int totalTime[2005];
int road[2005][2005];
bool isReached[2005];


class Res
{
public:
	int head;
	int count;
};
vector<Res> results;
void bfs(int start)
{
	queue<int> Q;
	vector<int> res;
	res.push_back(start);
	Q.push(start);
	isReached[start] = true;

	int sum = 0;
	while(Q.size()>0)
	{
		int cur = Q.front();
		Q.pop();

		for(int i=0;i<names.size();i++)
		{
			int rd = road[cur][i];
			if(rd>0)
			{
				sum += rd;
				road[cur][i]=0;
				road[i][cur]=0;
				if(!isReached[i])
				{
					Q.push(i);
					res.push_back(i);
					isReached[i] = true;
				}
			}

		}

	}
	if(sum>K && res.size()>2)
	{
		Res re;
		re.count = res.size();
		int head = res[(max_element(res.begin(),res.end(),[=](int a,int b){return totalTime[a]<totalTime[b];})-res.begin())];
		re.head = head;
		results.push_back(re);
	}
}
bool comp(const Res& a, const Res& b)
{
	return names[a.head]<names[b.head]; 
}
int main()
{
	scanf("%d %d",&N,&K);

	for(int i=0;i<N;i++)
	{
		char tmpna[5],tmpnb[5];
		int time;
		scanf("%s %s %d",tmpna,tmpnb,&time);

		string na(tmpna),nb(tmpnb);
		int ida,idb;

		vector<string>::iterator posa = find(names.begin(),names.end(),na);
		if(posa == names.end())
		{
			names.push_back(na);
			ida = names.size()-1;
		}else
			ida = posa-names.begin();

		vector<string>::iterator posb = find(names.begin(),names.end(),nb);
		if(posb == names.end())
		{
			names.push_back(nb);
			idb = names.size()-1;
		}else
			idb = posb-names.begin();
		road[ida][idb] += time;
		road[idb][ida] += time;
		totalTime[ida] += time;
		totalTime[idb] += time;
	}

	for(int i=0;i<names.size();i++)
	{
		if(!isReached[i])
		{
			bfs(i);
		}
	}
	sort(results.begin(),results.end(),comp);
	printf("%d\n",results.size());
	for(int i=0;i<results.size();i++)
	{
		printf("%s %d\n",names[results[i].head].c_str(),results[i].count);
	}
	return 0;
}



转载于:https://my.oschina.net/superpdm/blog/358513

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值