題目描述
有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\n"); else { for(int i=1;i<qaq;i++) printf("%d ",ans[i]); printf("%d\n",ans[qaq]); } }
