题目描述
有N个士兵(1<=N<=100),编号依次为1,2,...,N.队列训练时,指挥官要把士兵从高到矮排成一行,但指挥官只知道“1 比2 高,7 比 5高”这样的比较结果。
请编写一个程序,对于给出指挥官一些“a比b高”这样信息后,求出一种合理士兵从高到低的排列。
请编写一个程序,对于给出指挥官一些“a比b高”这样信息后,求出一种合理士兵从高到低的排列。
输入
输入文件:第一行为数N(N〈=100);表示士兵的个数。以下若干行每行两个数A,B表示A高于B(1<=A,B<=N且A!=B)。
输出
输出文件:给出一个合法的排队序列,格式如样例。如果没有答案,则输出-1。
拓补排序裸题。
首先我们先将讲一讲拓补排序。
拓补排序:
假设我们有一条边x->y
那么y的入度+1;
拓补排序就是对于一个有向无环图
每次找到入度为0的点,删除它并删除所有以他为起点的边
直到整个图为空
则输出顺序为拓补序
而应用的前提就是一道题目中做到一件事需要满足另一件事。而另一件事又需要满足另外一件事。以此类推。。
那么这种题目就很可能用到拓补排序
根据上面的思想我们很容易就能想到如何代码实现。
下面贴代码
#include<iostream> #include<cstdio> using namespace std; int de[101]; int que[10001]; int head[101]; int ans[101],qaq=0; struct edge{ int to,next; }g[10001]; int n,num; void ins(int u,int v) { g[++num].next=head[u]; head[u]=num; g[num].to=v; } void toposort() { int h=1,t=0; for(int i=1;i<=n;i++) { if(de[i]==0) que[++t]=i; } while(h<=t) { int tmp=que[h]; ans[++qaq]=tmp; for(int i=head[tmp];i;i=g[i].next) { if(!--de[g[i].to])que[++t]=g[i].to; } h++; } } int main(){ scanf("%d",&n); int x,y; while(~scanf("%d%d",&x,&y)) { de[y]++; ins(x,y); } toposort(); if(qaq<n)printf("-1 "); else { for(int i=1;i<qaq;i++) printf("%d ",ans[i]); printf("%d ",ans[qaq]); } }