蓝桥杯 算法提高 卡勒沃夫之弱水路三千(提高型)

算法提高 卡勒沃夫之弱水路三千(提高型)

Description

锦瑟年华谁与度 莫问情归处 只影向斜阳 剑吼西风 欲把春留驻

天涯芳草无归路 回首花无数 解语自销魂 弱袂萦春 尘缘不相误

在卡勒沃夫充满文学杀伤力的声音中,身处紫荆2号楼202B的四位远近高低各不同的室友纷纷回忆起了各自波澜起伏的过去,并对长在百草园,邻有百花谷的现状表达了各自的见解。

某Q:"…我小学就开窍了…她的父母说我很好,但是…今天又和北林的联系了…"

某X:"…差点就成了,结果到学校了…这个方法放假了我去对我的同桌用!…"

某W:"…"(千言万语不言中,有大量的故事等待考古)

某Z:"…为了来清华…咱们审美观不一样,不会抢…"

卡勒沃夫在这个不朽的夜话中搜集出了某人零散的历任女友资料,为了强迫某人将他出的题目的标程交出,现在卡勒沃夫需要一个能将这些零散信息整合起来的程序。伴随着雄壮委婉动人的音乐,身为程序设计快男(超女)的你降临了!卡勒沃夫正对着您做Orz状并请求着:“神牛啊请施舍给我一段程序把偶米头发~”。。

Input

输入描述:

第一行为一个不超过5的整数T,表示数据的组数。之后每组数据的一行为一个不超过100的整数n。之后n行每行有两个用单个空格隔开的字符串(每个字符串只有英文大小写字母,长度不超过10),为两位mm的名字。每行第一个mm先于第二个mm成为某人的女友。

在这里我们假装诅咒某人不会同时被两个或两个以上mm泡,某个mm抛弃了某人后不会再吃回头草,同时卡勒沃夫深邃的洞察力使得他收集到了充足的信息以确定某人女友的先后顺序。

在小数据组中出现的人物不超过13个

输入样例:
2
2
RY Unknown
YSZ RY
3
tomorrow yestoday
tomorrow today
today yestoday

Output

输出描述:

输出T行,每行对应一组数据,并按照mm们从先到后成为某人女友的顺序输出她们的名字,各个名字间用一个空格隔开。

输出样例:
YSZ RY Unknown
tomorrow today yestoday

解析

此题中说了mm们不吃回头草,因此可将此看作是有向无环图,因此可用拓扑排序输出顺序。可参考介绍拓扑排序的博客:拓扑排序
此题中说了此人不会同时被两人以上mm泡,因此每次入读为1的节点只有一个,因此可只用一个变量存起来,若有多个可考虑用队列queue按顺序输出。
要注意的是输出时要严格按照规定的格式,每行末尾不要有空格!

源码

#include <iostream>
#include <cstring>
#include <fstream>
#include <vector>
#include <map> 

using namespace std;

int main()
{
	//freopen("input/threethousand.txt","r",stdin);
	int t;
	map<string,vector<string> > table;  //邻接表 
	map<string,int> isExist;  //判断节点是否已经存在 
	map<string,int> in; //存储入度
	string isZero;  //存储入度为0的顶点,根据题意每次只会有一个入读为0的顶点 
	scanf("%d",&t); 
	while(t--)
	{
		int n;
		table.clear();
		in.clear();
		isExist.clear(); 
		string s1,s2;
		scanf("%d",&n);
		while(n--)
		{
			cin>>s1>>s2;
			if(!isExist.count(s1))
			{
				in[s1]=0;
				isExist[s1]++;
			}
			if(!isExist.count(s2))
			{
				in[s2]=0;
				isExist[s2]++; 
			}
			table[s1].push_back(s2);
			in[s2]++;
		}
		for(map<string,int>::iterator it=in.begin();it!=in.end();it++)
		{
			if(it->second==0)
			{
				isZero=it->first;
				cout<<isZero<<" ";
				in.erase(it);
				break; 
			}
		} 
		while(!table.empty())
		{
			string temp=isZero;
			for(int i=0;i<table[temp].size();i++)
			{
				in[table[temp][i]]--;
				if(in[table[temp][i]]==0)
				{
					isZero=table[temp][i];
					cout<<isZero;
				}
			}
			in.erase(isZero);
			table.erase(temp);
			if(!table.empty()) cout<<" "; 
		}
		if(t!=0) cout<<endl;
	}
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值