士兵排隊問題(拓補排序)(附簡要拓補排序思想及算法)


題目描述

有N個士兵(1<=N<=100),編號依次為1,2,...,N.隊列訓練時,指揮官要把士兵從高到矮排成一行,但指揮官只知道“1 比2 高,7 比 5高”這樣的比較結果。
請編寫一個程序,對於給出指揮官一些“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]); 
    } 
} 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM