• 6-06. 理性任务调度(25)(拓扑排序啊 ZJU_PAT)


    主题链接:http://pat.zju.edu.cn/contests/ds/6-06


    假定一个project项目由一组子任务构成,子任务之间有的能够并行运行。有的必须在完毕了其他一些子任务后才干运行。

    “任务调度”包含一组子任务、以及每一个子任务能够运行所依赖的子任务集。

    比方完毕一个专业的全部课程学习和毕业设计能够看成一个本科生要完毕的一项project,各门课程能够看成是子任务。

    有些课程能够同一时候开设,比方英语和C程序设计,它们没有必须先修哪门的约束;有些课程则不能够同一时候开设,由于它们有先后的依赖关系。比方C程序设计和数据结构两门课,必须先学习前者。

    可是须要注意的是,对一组子任务,并非随意的任务调度都是一个可行的方案。

    比方方案中存在“子任务A依赖于子任务B,子任务B依赖于子任务C,子任务C又依赖于子任务A”,那么这三个任务哪个都不能先运行,这就是一个不可行的方案。你如今的工作是敲代码判定不论什么一个给定的任务调度是否可行。

    输入格式说明:

    输入说明:输入第1行给出子任务数N(<=100)。子任务按1~N编号。随后N行。每行给出一个子任务的依赖集合:首先给出依赖集合中的子任务数K,随后给出K个子任务编号,整数之间都用空格分隔。

    输出格式说明:

    假设方案可行。则输出1,否则输出0。

    例子输入与输出:

    序号 输入 输出
    1
    4
    0
    1 1
    1 1
    2 2 3
    
    1
    
    2
    12
    0
    0
    2 1 2
    0
    1 4
    1 5
    2 3 6
    1 3
    2 7 8
    1 7
    1 10
    1 7
    
    1
    
    3
    4
    1 4
    2 1 4
    1 2
    1 3
    
    0

    PS:

    用拓扑排序,如有节点不能被删除则有环!

    代码例如以下:

    #include <cstdio>
    #include <cstring>
    #define MAXN 517
    int G[MAXN][MAXN];//路径
    int in_degree[MAXN];//入度
    int ans[MAXN];
    int n, m, x, y;
    int i, j;
    int flag = 0;
    void toposort()
    {
        flag = 0;
        for(i = 1; i <= n; i++)
        {
            for(j = 1; j <= n; j++)
            {
                if(G[i][j])
                {
                    in_degree[j]++;
                }
            }
        }
        for(i = 1; i <= n; i++)//从最小的開始寻找,
        {
            //这样保证了有多个答案时序号小的先输出
            int k = 1;
            while(in_degree[k] != 0)//寻找入度为零的点
            {
                k++;
                if(k > n)
                {
                    flag = 1;
                    break;
                }
            }
    
            ans[i] = k;
            in_degree[k] = -1;
            //更新为-1,后边检測不受影响,相当于删除节点
            for(int j = 1; j <= n; j++)
            {
                if(G[k][j])
                    in_degree[j]--;//相关联的入度减1
            }
        }
    }
    
    void init()
    {
        memset(in_degree,0,sizeof(in_degree));
        memset(ans,0,sizeof(ans));
        memset(G,0,sizeof(G));
    }
    
    int main()
    {
        while(~scanf("%d",&n))
        {
            init();
            for(i = 1; i <= n; i++)
            {
                scanf("%d",&m);
                for(int j = 0; j < m; j++)
                {
                    scanf("%d",&y);
                    G[i][y] = 1;
                }
            }
            toposort();
            if(flag)
            {
                printf("0
    ");
            }
            else
                printf("1
    ");
        }
        return 0;
    }
    


    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    12-14面向对象--抽象基类、接口、委托
    关于 try catch catch
    C# using 三种使用方式
    互斥锁(Mutex)
    C#中Monitor类、Lock关键字和Mutex类
    System.Data.SQLite
    Dictionary<TKey, TValue> 类
    AttributeTargets 枚举
    C# is和as操作符
    合并委托(多路广播委托)
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4664191.html
Copyright © 2020-2023  润新知