【PAT 甲级】A1034 Head of a Gang(30分)

坑点提示:数组应该开到2000+,因为总共可能有1000条记录…否则会有一个测试点提示段错误!
思路:一个简单的DFS…没啥特殊的,一定一定要想好怎么保存权值…我是维护了一个边值记录和一个点值数组…
…我感觉Dev-C++没有函数提示这个是真的太坑啦,每次要想好长时间qwq

#include <bits/stdc++.h>
using namespace std;
struct node
{
	string name;
	int time;
};
vector<node> v[2048];
bool visited[2048];
int T[2048],psum=0,tsum=0,h=-1,cluster=0;
map<string,int> m;
map<string,int> c;
string head[2048];
int sti(string s)
{
	if(m.find(s)!=m.end()) return m[s];
	else
	{
		m[s]=psum;
		return psum++;
	}
}
string its(int value)
{
	for(map<string,int>::iterator it=m.begin();it!=m.end();it++)
	{
		if(it->second == value)
		return it->first;
	}
}
void DFS(int index)
{
	visited[index]=true;
	cluster++;
	if(T[index]>T[h]) h=index;		//update the head of the gang
	for(int i=0;i<v[index].size();i++)
	{
		tsum+=v[index][i].time;
		int temp=sti(v[index][i].name);
		if(!visited[temp])
		DFS(temp);
	}
}
bool cmp(string a,string b)
{
	for(int i=0;i<3;i++)
	if(a[i]!=b[i]) return a[i]<b[i];
	return 1;
}
int main(void)
{
	int n,k,cnt=0;
	scanf("%d%d",&n,&k);
	memset(T,0,sizeof(T));
	for(int i=0;i<n;i++)
	{
		string str1,str2;
		int t,p1,p2;
		node n1,n2;
		bool flag=false;
		cin>>str1>>str2>>t;	
		p1=sti(str1);p2=sti(str2);
		for(int j=0;j<v[p1].size();j++)
		{
			if(sti(str2) == sti(v[p1][j].name))		//the edege has been created
			{
				flag=true;
				v[p1][j].time+=t;
				break;
			}
		}
		if(flag)									//the edge has been created
		{
			for(int j=0;j<v[p2].size();j++)
			if(sti(str1) == sti(v[p2][j].name))
			{
				v[p2][j].time+=t;
				break;
			}
		}
		else
		{
			n1.name=str1;n1.time=t;
			n2.name=str2;n2.time=t;
			v[p1].push_back(n2);v[p2].push_back(n1);
		}
		T[p1]+=t;T[p2]+=t;
		visited[i]=false;
	}
	for(int i=0;i<n;i++)
	{
		if(!visited[i])
		{
			tsum=0;h=i;cluster=0;
			DFS(i);
			tsum/=2;
		}
		else continue;
		if(tsum>k && cluster>2)									//one possible answer
		{
			head[cnt]=its(h);
			c[head[cnt]]=cluster;
			cnt++;
		}
	}
	//sort
	sort(head,head+cnt,cmp);
	//output
	cout<<cnt<<endl;
	for(int i=0;i<cnt;i++)
	{
		cout<<head[i]<<" "<<c[head[i]];
		if(i!=cnt-1) cout<<endl;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值