• 士兵排队问题(拓补排序)(附简要拓补排序思想及算法)


    题目描述

    有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
    "); 
        else 
        { 
            for(int i=1;i<qaq;i++) 
            printf("%d ",ans[i]); 
            printf("%d
    ",ans[qaq]); 
        } 
    } 
  • 相关阅读:
    Cookie的定义和分类,及优缺点
    网页开发和设计
    电视精灵(新手练习项目)
    C#体检套餐项目
    C#简单的对象交互
    那些年我们学过的构造函数(构造方法,C#)
    员工打卡课后小项目
    SpringMVC类型转换器
    SpringMVC 异常处理3种方案
    SSH整合(一)hibernate+spring
  • 原文地址:https://www.cnblogs.com/ghostfly233/p/6890040.html
Copyright © 2020-2023  润新知