zoukankan      html  css  js  c++  java
  • 拓扑排序入门

    话不多说,先上图!!!

    聪明的你,可以发现每次都是先输出入度为0的点(类似于入口),然后删除与此点相关的边,然后继续同样的操作。经过如此反复操作,如果图中的点都输出了,就说明此图是无环有向图,否则就是有环图。

    比如说这里的环CED,BD,环中任意一点入度都不为0,根本找不到入口。所以没法遍历完所有的点

    对于题目给定了众多两点之间的优先级关系,然后让你判断所有点之间的是否构成优先级。

    • 现在来介绍一个模板题
    有N个比赛队(1<=N<=500),编号依次为1,2,3,。。。。,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道每场比赛的结果,即P1赢P2,用P1,P2表示,排名时P1在P2之前。现在请你编程序确定排名。 

    Input输入有若干组,每组中的第一行为二个数N(1<=N<=500),M;其中N表示队伍的个数,M表示接着有M行的输入数据。接下来的M行数据中,每行也有两个整数P1,P2表示即P1队赢了P2队。 
    Output给出一个符合要求的排名。输出时队伍号之间有空格,最后一名后面没有空格。 

    其他说明:符合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前;输入数据保证是正确的,即输入数据确保一定能有一个符合要求的排名。 

    • Sample Input
    4 3
    1 2
    2 3
    4 3
    • Sample Output
    1 2 4 3

    简单来说,存图时需要记录每个点的入度数(用数组),以及记录一个出度邻接表(vector)。把入度为0的点都放入到队列中。队列每出队一个,就将此点出度相连的点入度-1,减的过程中,又出现了入度为0点的时候,再把入度为0的点加入到队列。

    最后遍历一遍入度数的数组,若数组中全入度为0,则图遍历完毕,不存在环,否则肯定存在环。

    #include <bits/stdc++.h>
    using namespace std;
    const int NN = 550;
    
    int in[550];//in[i]:点i的入度次数 
    int N,M;
    int main(){
        while(cin>>N>>M){
            vector<int> out[550];//out[i]:点i出度相连的点 
            priority_queue<int, vector<int>, greater<int> > q;//优先队列,从小到大排列 
            memset(in,0,sizeof(in));
            int win,lo; //赢 输 
            for(int i = 1;i<=M;i++){
                scanf("%d%d",&win,&lo);
                out[win].push_back(lo); //以赢->输的关系存储的 
                in[lo]++;//谁输了,谁的入度+1 
            }
            for(int i = 1;i<=N;i++){ //将入度为0的点加入到优先队列 
                if(in[i] == 0)
                    q.push(i);
            }
            int tag = 0;//题目要求,末尾不加空格 
            while(!q.empty()){
                int x = q.top();
                q.pop();//删除入度为0的点 
                if(tag)
                    cout<<" ";
                tag = 1;
                cout<<x;
                for(int i = 0;i<out[x].size();i++){ //将x出度相连的点入度-1,相当于删除边 
                        in[out[x][i]]--;
                        if(in[out[x][i]] == 0){//某点度为0,就加入到优先队列中 
                            q.push(out[x][i]);
                        }
                }
            }
            cout<<endl;
            
        }
        
        return 0;
    }
  • 相关阅读:
    【Educational Codeforces Round 101 (Rated for Div. 2) C】Building a Fence
    【Codeforces Round #698 (Div. 2) C】Nezzar and Symmetric Array
    【Codeforces Round #696 (Div. 2) D】Cleaning
    【Codeforces Round #696 (Div. 2) C】Array Destruction
    【Educational Codeforces Round 102 D】Program
    【Educational Codeforces Round 102 C】No More Inversions
    【Good Bye 2020 G】Song of the Sirens
    【Good Bye 2020 F】Euclid's nightmare
    使用mobx入门
    requestAnimationFrame 控制速度模拟setinterval
  • 原文地址:https://www.cnblogs.com/bigbrox/p/11316059.html
Copyright © 2011-2022 走看看