HPU-1706-牛B

以下题目高能...不要问我哪的题.........

1706: 牛B

时间限制: 1 Sec   内存限制: 128 MB
提交: 25   解决: 7
[ 提交][ 状态][ 讨论版]

题目描述

一群来自日本恐怖分子带着AK47,火箭弹,开着坦克,带着飞机,强行洗劫了一家位于日本的银行,但是众所周知日本人比较奸诈,比较野蛮,但是恐怖分子更加残忍,他们烧杀抢掠无情的蹂躏着日本人,并且最终成功将这家银行的钱全部抢走。但是由于日本人比较贪婪这些恐怖分子总想一个人独占抢来的所有钱。当然这引起了其他人的不满为此他们为了独占所有的钱进行自相残杀。已知这群恐怖分子有N个人(N<=200)并且知道MM<=1000)种关系每行两个人说明前面的人能杀死后面的人现在请你判断是否存在独一无二的一种顺序如果存在输出这个排名由最牛B的到最弱B依次输出这群日本人的名字如果不存在或数据有冲突(有冲突即日本人A杀死日本人B后日本人B又复活将日本人A杀死(日本人太残暴了)等等)输出”baga”.

输入

输入第一行两个整数N和M,N代表有N(2=<N<=200)个日本恐怖分子,M组关系(1=<M<1000)接下来每行两个字符串分别代表日本人的名字第一个日本人能杀死第二个日本人。输入数据保证N个人的名字都出现过并且人名的字符不超过20个。

输出

输出如果存在一组独一无二从牛B到弱B的排名输出这个排名中日本人的名字由牛B到弱B依次输出如果不存在或有冲突输出”baga”;

样例输入

4 3
anbeijinsan gangcunningci
gangcunningci songjingshigen
songjingshigen dongtiaoyingji
4 3
anbeijinsan xiaoquanyilang
gancunningc shanben56
anbeijinsan shanben56
2 2
anbeijinsan gangcunningci
gangcunningci anbeijinsan

样例输出

anbeijinsan gangcunningci songjingshigen dongtiaoyingji
baga
baga


RT....
拓扑排序,需要将字符串对应成编号,没学map.哈希..转换的好麻烦...
前边还有一篇也是这样的:连接贴出来,里边对转换的部分解释的比较详细http://blog.csdn.net/kflcg/article/details/47746639
为了好题拼着做出来了......
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<algorithm>
#include<functional>
#define max 1010
#define INF 0x3f3f3f3f
using namespace std;
int N,M,map[max][max],pre[max],w;//人数,关系数,关系矩阵,前置元素个数,可排序的人数 
struct str{
	char name[40];
}place[10010];//讲人名对应成序号 
char ans[1000][40];//排序的存名字 
void topu(){
	int k;
	int cnt=0;
	priority_queue<int,vector<int>,greater<int> >q;
	for(int n=1;n<=N;n++){
		if(!pre[n]){
			q.push(n);
			cnt++;
			if(cnt>1){//一循环有两个pre为零说明这俩无先后,baga 
				puts("baga");
				return;
			}
		}
	}
	int t=0;
	while(!q.empty()){
		int top=q.top();
		q.pop();
		w++;
		strcpy(ans[t],place[top].name);
		t++;//t最后应等于N 
		pre[top]--;
		int cnt=0;
		for(int n=1;n<=N;n++){
			if(map[top][n]){
				pre[n]--;
				if(!pre[n]){
					q.push(n);
					cnt++;
					if(cnt>1){
						puts("baga");//同上,一循环有两个pre为零说明这俩无先后,baga 
						return;
					}
				}
					
			}
		}
	}
	if(w!=N)//参与排序的和总人数不等说明有环,baga 
		puts("baga");
	else{
		for(int i=0;i<t;i++){//可以排序输出答案 
			if(i)
				putchar(' ');//除行头名间空格 
			printf("%s",ans[i]);
		}
		puts("");//换行 
	}
}

int main(){
	while(~scanf("%d%d",&N,&M)){
		char p[20],q[20];
		for(int i=0;i<10010;i++){
			memset(place[i].name,'\0',sizeof(place[i].name));//清空人名结构体 
		} 
		memset(map,0,sizeof(map));
		memset(pre,0,sizeof(pre));
		int a,b,K=3;
		scanf("%s%s",place[1].name,place[2].name);
		map[1][2]=1;
		pre[2]++;
		for(int m=1;m<M;m++){
			memset(p,'\0',sizeof(p));
			memset(q,'\0',sizeof(q));
			scanf("%s%s",p,q);
			a=INF;b=INF;
			for(int k=1;k<=N;k++){
				if(!strcmp(p,place[k].name)){
					a=k;
				}
				if(!strcmp(q,place[k].name)){
					b=k;
				}
			}
			if(a==INF){
				a=K;
				strcpy(place[K].name,p);
				K++;
			}
			if(b==INF){
				b=K;
				strcpy(place[K].name,q);
				K++;
			}
			if(map[a][b]==0){
				map[a][b]=1;
				pre[b]++;
			}
		}
		w=0;
		topu();
	}
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值