南邮 OJ 2080 KSS的金牌梦1

KSS的金牌梦1

时间限制(普通/Java) :  3000 MS/ 9000 MS          运行内存限制 : 65536 KByte
总提交 : 76            测试通过 : 11 

比赛描述

KSSnupt集训队里公认最具有金牌实力的选手,熟练掌握多种金牌算法但是由于队友水平太菜和自身情绪不稳定一直没能拿到金牌。KSS为了圆梦,想为自己制定一个训练计划,那么问题来了:

ACM有许多算法之间单方面依赖关系的,比如:想学会A,就必须先学B,由于KSS很聪明,所以它可以学完AB当然也存在两种多种算法相互交融的情况比如想学会A,就必须先学B想学会B,就必须先学A,这种情况KSS不知从何下手了

现在给出KSS打算学习的一些算法之间的依赖关系KSS尽自己最大的努力去学习这些算法。再给出比赛出现的算法,如果KSS能学会超过70%的比赛算法他就能圆梦否则他只能含恨退役。



输入

多组测试用例

第一行一个整数N(0<=N<=250000)表示有N算法存在依赖关系,保证涉及的算法总数不超过500


接下来N行每行有两个字符串(以空格分割),表示前一个算法依赖后一个算法N+1有一个整数M(0<M<=1000)表示比赛会出现M算法,接下来M每行有一个字符串表示比赛出现的算法。(字符串保证不含空格)

输出

如果KSS可以圆梦,输出“Excelsior!否则,输出“KSS have a dream!。(不用输出引号)

样例输入

4
Aho-Corasickautomaton KMP
Aho-Corasickautomaton trietree
Inclusion-ExclusionPrinciple Mobiusinversion
Mobiusinversion Inclusion-ExclusionPrinciple
5
KMP
trietree
Aho-Corasickautomaton
Splay
Suffixarray

样例输出

KSS have a dream!

提示

对于样例,KSS可以学会KMPtrietreeAho-Corasickautomaton但是不能学会Inclusion-ExclusionPrincipleMobiusinversion所以只能掌握60%比赛算法


题目来源

hjp





#include<iostream>
#include<string>
#include<map>
#include<queue>
#define MAX_M 1001
using namespace std;

int N;							//依赖的个数
int stringNo;					//总共的算法个数
map<string,int> nameToIndex;	//算法名转换为数组下标
vector<int> nexts[MAX_M];		//第i个算法的后继节点们,即学他们之前必须先学i
int preNum[MAX_M];				//第i个算法的前驱个数

void init(){
	stringNo = 0;
	nameToIndex.clear();
	for(int i=0; i<MAX_M; i++){
		nexts[i].clear();
		preNum[i] = 0;
	}
}

void addDepend(){
	int i,j;
	string s1,s2;
	while(N--){
		cin>>s1>>s2;
		if(nameToIndex.count(s1)){
			i = nameToIndex[s1];
		}else{
			i = stringNo++;
			nameToIndex[s1] = i;
//			cout<<i<<'\t'<<s1<<endl;
		}
		if(nameToIndex.count(s2)){
			j = nameToIndex[s2];
		}else{
			j = stringNo++;
			nameToIndex[s2] = j;
//			cout<<j<<'\t'<<s2<<endl;
		}
		nexts[j].push_back(i);
		preNum[i]++;
	}
}

void topSort(){
	bool flag = 1;
	int i,j,len,k;
	while(flag){
		flag = 0;
		for(i=0;i<stringNo;i++){
			if(0==preNum[i] && !nexts[i].empty()){
				len = (int)nexts[i].size();
				for(j=0; j<len; j++){
					k = nexts[i][j];
					preNum[k]--;
					if(0==preNum[k]){
						flag = 1;
					}
				}
			}
			nexts[i].clear();
		}
	}
}

void printResult(){
	int M,i,num=0;
	string s;
	cin>>M;
	for(i=0;i<M;i++){
		cin>>s;
		if(nameToIndex.count(s) && 0 == preNum[ nameToIndex[s] ] ){
			num++;
//			cout<<s<<"\tOK"<<endl;
		}else{
//			cout<<s<<"\tcan't learn"<<endl;
		}
	}
	if(num*10 > M*7){
		cout<<"Excelsior!"<<endl;
	}else{
		cout<<"KSS have a dream!"<<endl;
	}
}

int main(){
//	freopen("text.txt","r",stdin);
	while(cin>>N){
		init();
		addDepend();
		topSort();
		printResult();
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值