hpuoj 1706: 牛B【正向拓扑】【建图】

1706: 牛B

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

题目描述

一群来自日本恐怖分子带着AK47,火箭弹,开着坦克,带着飞机,强行洗劫了一家位于日本的银行,但是众所周知日本人比较奸诈,比较野蛮,但是恐怖分子更加残忍,他们烧杀抢掠无情的蹂躏着日本人,并且最终成功将这家银行的钱全部抢走。但是由于日本人比较贪婪这些恐怖分子总想一个人独占抢来的所有钱。当然这引起了其他人的不满为此他们为了独占所有的钱进行自相残杀。已知这群恐怖分子有N个人(N<=200)并且知道M(M<=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
此题不难重在建图:注意:1、所要输出的序列必须是独一无二的,即除了最牛B的人其余的人必定能被另一个人杀死,且是一级一级按顺序的比如(共有四个人ABCD  则顺序为 A杀死B,B杀死C,C杀死D)        那么如何判断是否独一无二呢?   很简单,就是在入队列时,每一次队列中都必定只有一个元素     2、不能成环,这个就容易了,只需判断最后排序完成之后判断参与排序的人数是否等于总人数即可
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
int n,m;
char a[50],b[50];
char str[210][50];
int map[210][210],vis[210];
int s[210][210];
int d[210];
void qing()
{
	memset(map,0,sizeof(map));
	memset(vis,0,sizeof(vis));
	memset(d,0,sizeof(d));
	memset(s,0,sizeof(s));
	memset(a,‘\0‘,sizeof(a));
	memset(b,‘\0‘,sizeof(b));
	memset(str,‘\0‘,sizeof(str));
}
void getmap()
{
	int q,p,i,j,sum=1;
	qing();
	for(i=1;i<=m;i++)
	{
		q=p=-1;
		scanf("%s%s",a,b);
		for(j=1;j<sum;j++)
		{
			if(strcmp(str[j],a)==0)
			{
				q=j;
				map[i][1]=j;
			}
			if(strcmp(str[j],b)==0)
			{
				p=j;
				map[i][2]=j;
			}
			if(q!=-1&&p!=-1)
			break;
		}

		if(q==-1)
		{
			q=sum++;
			map[i][1]=q;
			strcpy(str[q],a);
		}

		if(p==-1)
		{
			p=sum++;
			map[i][2]=p;
			strcpy(str[p],b);
		}

	}
	for(i=1;i<=n;i++)
	{
		if(!s[map[i][1]][map[i][2]])
		{
			s[map[i][1]][map[i][2]]=1;
			vis[map[i][2]]++;
		}
	}
}
void tuopu()
{
	int i,j,ok=0;
	int ant=0;
	queue<int>q;
	while(!q.empty())
	q.pop();
	for(i=1;i<=n;i++)
		if(vis[i]==0)
			q.push(i);
	int u,ans=0;
	while(!q.empty())
	{
		if(q.size()>1)//判断是否独一无二
		{
			ok=1;
			break;
		}
	    u=q.front();
		q.pop();
		d[ans++]=u;
		for(i=1;i<=n;i++)
		{
			if(s[u][i])
			{
				vis[i]--;
				if(!vis[i])
				q.push(i);
			}
		}
	}
	if(ans!=n)//判断是否成环
	    ok=1;
	if(ok)
	printf("baga\n");
	else
	{

		for(i=0;i<ans-1;i++)
		printf("%s ",str[d[i]]);
		printf("%s\n",str[d[ans-1]]);
	}
}
int main()
{
	int i,j;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		getmap();
		tuopu();
	}
	return 0;
}

  

  

时间: 2024-10-06 00:56:04

hpuoj 1706: 牛B【正向拓扑】【建图】的相关文章

POJ 3281 Dining (网络流最大流 拆点建图 Edmonds-Karp算法)

Dining Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10159   Accepted: 4676 Description Cows are such finicky eaters. Each cow has a preference for certain foods and drinks, and she will consume no others. Farmer John has cooked fabulo

hdu 4857/BestCoder Round#1 1001(拓扑排序+逆向建图)

此题需细致分析题目,否则题意easy理解错误.应注意以下这样的情况 本题意思尽可能让最小的排的靠前.然后次小的尽量靠前.依次下去 如 input: 1 3 1 3 1 output: 3 1 2 解析:我们应让1尽可能的排在前面.然后尽可能的让2排的靠前.. .所以 2 3 1的结果是错误的 思路:拓扑排序(逆向建图+队列)//为解决上述列子.假设我们正向建图.每次选择入度为零最小的编号输出则无法满足上述案例. 假设我们尝试逆向建图,每次选择入度为零的最大编号输出则刚刚是正确结果的逆序(省赛并查

HDU2647(拓扑排序+反向建图)

题意不说了,说下思路. 给出的关系是a要求的工资要比b的工资多,由于尽可能的让老板少付钱,那么a的工资就是b的工资+1,可以确定关系为a>b,根据拓扑排序建边的原则是把"小于"关系看成有向边,那么我们可以建边v->u. #include <stdio.h> #include <string.h> #include <string> #include <iostream> #include <algorithm> #

HDU1535Invitation Cards(有向图,正向建图和反向建图各spfa一次)

Invitation Cards Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 2374    Accepted Submission(s): 1151 Problem Description In the age of television, not many people attend theater performances.

POJ 3687 反向建图+拓扑

Labeling Balls Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11146   Accepted: 3192 Description Windy has N balls of distinct weights from 1 unit to N units. Now he tries to label them with 1 to N in such a way that: No two balls share

hdu 2647 (拓扑排序 邻接表建图的模板) Reward

题目链接http://acm.hdu.edu.cn/showproblem.php?pid=2647 老板给员工发工资,每个人的基本工资都是888,然后还有奖金,然后员工之间有矛盾,有的员工希望比某员工的奖金多,老板满足了所以员工的这种心思,而且老板下午发的总工资最少,问最少是多少?比如 a b 表示a的工资比b要高(高一块钱),当出现a b   b c   c a这种环的时候输出-1 拓扑排序http://www.cnblogs.com/tonghao/p/4721072.html 小指向大

HDU4857——逃生(反向建图+拓扑排序)

逃生 Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行. 现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必须在b之前.同时,社会是不平等的,这些人有的穷有的富.1号最富,2号第二富,以此类推.有钱人就贿赂负责人,所以他们有一些好处.负责人现在可以安排大家排队的顺序,由于收了好处,所以他要让1号尽量靠前,如果此时还有多种情况,就再让2号尽量靠前,如果还有多种情况,就让3号尽量靠前,以此类推.那么你就要安排大家的顺序.我们保证一

[CF825E] Minimal Labels(反向建图,拓扑排序)

题目链接:http://codeforces.com/problemset/problem/825/E 题意:给一个有向图,求一个排列,这个排列是每一个点的序号,使得序号对应的点的排序符合拓扑序并且这个排列字典序最小. 直接跑字典序最小的拓扑排序是不行的,因为那样只是确保点的字典序而非这个排列的字典序,比如这个数据: 10 15 2 反过来考虑,点号大的入度为0的点一定排在后面,这个位置确定了.但是点好小的入度为0的未必一定排在前面,因为这个点之前可能有入度不为0,但是与此点无关的点在前面,按题

【建图+拓扑判环】BZOJ3953: [WF2013]Self-Assembly

Description 自动化学制造(Automatic Chemical Manufacturing,简称ACM)正在对一个叫自组装(self-assembly)的过程进行实验.在这个过程中,有着天然相互吸引力的分子被混合在溶液中,任由它们聚集组合成更大的结构.但是有一个问题随之出现:有时候,分子们会把自身组合成一个无限大的结构体,以至于把容器撑爆. 你需要写一个程序来判断一个给定的分子集合是否可能组合成一个无限大的结构体.为了使问题简化,你可以作以下两个假设: 1. 问题被限制在二维平面上.