[poj2367]Genealogical tree_拓扑排序

Genealogical tree poj-2367

    题目大意:给你一个n个点关系网,求任意一个满足这个关系网的序列,使得前者是后者的上级。

    注释:1<=n<=100.

      想法:刚刚学习toposort,什么是toposort?

        就是每一个点的遍历或选取有先决条件,那么我们可以通过队列或者栈将控制当前点的点先遍历,这样弹栈或出队的序列,就是toposort的结果

      我们先附上模板

int v[100100];//入度
bool map[110][110]={false};//是否存在控制与被控制
int ans[110];//出队序列
int tot;
int n;void toposort()
{
	queue<int>q;
	for(int i=1;i<=n;i++)
	{
		if(!v[i]) q.push(i);
	}
	while(q.size())//其实toposort不同于spfa和bfs在于时间复杂度是O(n)的
	{
		int x=q.front(); q.pop(); ans[++tot]=x;//直接更新
		for(int i=1;i<=n;i++)
		{
			if(map[x][i]==1)
			{
				v[i]--;
				if(v[i]==0) q.push(i);
			}
		}
	}
}

     最后,附上丑陋的代码... ...

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
int v[100100];//入度
bool map[110][110]={false};//是否存在控制与被控制
int ans[110];//出队序列
int tot;
int n;void toposort()
{
	queue<int>q;
	for(int i=1;i<=n;i++)
	{
		if(!v[i]) q.push(i);
	}
	while(q.size())//其实toposort不同于spfa和bfs在于时间复杂度是O(n)的
	{
		int x=q.front(); q.pop(); ans[++tot]=x;//直接更新
		for(int i=1;i<=n;i++)
		{
			if(map[x][i]==1)
			{
				v[i]--;
				if(v[i]==0) q.push(i);
			}
		}
	}
}
void original()
{
	memset(map,false,sizeof map);
	memset(ans,0,sizeof ans);
	tot=0;
	memset(v,0,sizeof v);
}
int main()
{
	while(~scanf("%d",&n))
	{
		original();
		for(int a,i=1;i<=n;i++)
		{
			while(1)
			{
				scanf("%d",&a);
				if(!a) break;
				v[a]++;
				map[i][a]=1;
				map[a][i]=1;
			}
		}
		toposort();
		for(int i=1;i<=tot;i++)
		{
			printf("%d ",ans[i]);
		}
		puts("");
	}
	return 0;
}

     小结:toposort是一种处理存在先决条件问题或上下级关系的主要手段之一,它在一般情况下作为一个辅助的条件。比如我们可以维护一个appear数组表示一个数是否出现过从而达到判环的效果(NOI2009植物大战僵尸),我们也可以通过拓扑排序来处理一些比较容易用图来表达的问题(没有上司的舞会)

 

全部评论

相关推荐

小厂面经,也是我的处女面(30min)1.自我介绍2.spring&nbsp;boot的自动装配原理(好多类和接口的单词都忘了全称是啥了,就说了记得的单词,流程应该说对了吧)3.有用过redis吗?主要是用在实现什么功能(说了技术派用redis的zset来实现排行榜)5.有了解过Redisson吗?讲一下对于分布式锁的了解以及在什么场景下应用(说了秒杀场景)6.对mysql有了解吗?包括它的索引优化和创建(把想起来的全说了)7.了解设计模式吗?比如单例模式,为什么要使用单例模式,它的优点是什么(昨天刚看的设计模式)8.工厂模式有了解吗?主要的使用场景是?(也是昨天刚看的)9.场景题:有7个服务器,需要在早上十点定时的向数据库中的用户表中的用户发短信,如果做到发送的消息不重复,且如果发送失败了需要知道是到哪个用户失败了,这样下次就直接从这个用户开始(我答了用spring&nbsp;task来实现定时,用分布式锁来保证只有一份服务器可以发送消息,用消息队列来存储消息,然后用消息确认机制来保证错误信息的记录,以及在数据库或者业务层面完成消息消费的幂等性)10.场景题:如果在系统启动的时间就将数据库的所有用户相关的信息都读到一个hashmap中(这个没啥思路,没答好)27届的投了一个星期终于有一个面试了,大部分公司都只招26的
inari233:已oc,拒了
查看9道真题和解析
点赞 评论 收藏
分享
03-29 14:19
门头沟学院 Java
你背过凌晨4点的八股文么:加油同学,人生的容错率很高,只是一个暑期罢了,后面还有很多机会!
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务