• UVA 10305 Ordering Tasks(拓扑排序的队列解法)


    题目链接:

    https://vjudge.net/problem/UVA-10305#author=goodlife2017

    题目描述

    John有n个任务,但是有些任务需要在做完另外一些任务后才能做。

    输入

    输入有多组数据,每组数据第一行有两个整数1 <= n <= 100mn是任务个数(标记为1n),m两个任务直接关系的数量。在此之后,有m行,每行有2个整数ij,代表任务i必须在任务j之前完成。用n = m = 0结束整个输入。

    输出

    每一个数据对应一行n个整数,代表任务完成的顺序。

    样例输入

    	5 4
    	1 2
    	2 3
    	1 3
    	1 5
    	0 0

    样例输出

    	1 4 2 5 3
     1 /*
     2 问题 给出变量的个数n和m个二元组,输出任意一个从小到大的排序
     3 解题思路 由题中所给的m个二元组可以得到每个点的入度,创建一个队列,先将入度为0的点加入队列,
     4 然后依次出队,出队过程中将以该点为起点的那条边的终点的入度减去1,如果该点的入度变为0,就将该点也加入队列, 
     5 直到队列为空。 如果队列为空后,出队的点的个数等于总个数,则说明有拓扑序列,否则说明图内有环,够不成拓扑序列。 
     6 */
     7 #include<iostream>
     8 #include<cstdio>
     9 #include<cstring>
    10 #include<vector>
    11 #include<queue>
    12 using namespace std;
    13 
    14 const int maxn=110;
    15 
    16 vector<int> g[maxn];//表示以g[i]为起点的边,比如表示1——2和1——3这两条边,g[1]中第一个元素为2,第二个元素为3 
    17 int rd[maxn];
    18 int topo[maxn];
    19 
    20 bool toposort(int n);
    21 
    22 int main()
    23 {
    24     int m,n,i,u,v,j,flag; 
    25     while(scanf("%d%d",&n,&m), n + m != 0){
    26         for(i=1;i<=m;i++){
    27             scanf("%d%d",&u,&v);
    28             flag=0;
    29             for(j=0;j<g[u].size();j++)
    30                 if(g[u][j] == v)
    31                 {
    32                     flag=1;
    33                     break;
    34                 }
    35             if(!flag) g[u].push_back(v);
    36         }
    37         
    38         if(toposort(n)){
    39             for(i=0;i<n-1;i++)
    40                 printf("%d ",topo[i]);
    41             printf("%d
    ",topo[n-1]);
    42         }
    43         
    44         for(i=0;i<=n;i++)
    45             g[i].clear();
    46     }
    47     return 0;
    48 }
    49 
    50 bool toposort(int n)
    51 {
    52     int i,j;
    53     memset(rd,0,sizeof(rd));
    54     for(i=1;i<=n;i++){
    55         for(j=0;j<g[i].size();j++){
    56             rd[ g[i][j] ]++;
    57         }
    58     }
    59     
    60     int t=0;
    61     queue<int> q;
    62     for(i=1;i<=n;i++)
    63         if(rd[i]==0){
    64             q.push(i);    
    65         }
    66     
    67     int x;    
    68     while(!q.empty()){
    69         x=q.front();
    70         q.pop();
    71         topo[t++]=x;
    72         for(i=0;i<g[x].size();i++){
    73             j=g[x][i];
    74             rd[ j ]--;
    75             
    76             if(rd[j]==0)
    77                 q.push(j);
    78         }
    79     }
    80     
    81     if(t==n) return 1;
    82     return 0;
    83 }
  • 相关阅读:
    /etc/alternatives
    linux Link
    JVM程序计数器
    面向对象的内存分析
    SpringBoot项目简单实现给邮箱发送验证码
    注解式SQL Select语句判空
    SQL Update时参数判空:传入参数为空时不更新对应字段,不为空时才更新
    MySQL数据库误Update找回数据的方法
    用户-角色-权限系统概述
    将一个数组转换为List
  • 原文地址:https://www.cnblogs.com/wenzhixin/p/8641375.html
Copyright © 2020-2023  润新知