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;
    }
  • 相关阅读:
    When to Partition a Table and an Index
    Hello, world
    提交
    SubmitOncePage:解决刷新页面造成的数据重复提交问题
    压缩ASP.NET中的ViewState
    asp.net千奇百怪的日历
    ICallbackEventHandler实现
    xml數據
    CrystalReports
    [转]Microsoft Visual Studio 2005中使用水晶报表
  • 原文地址:https://www.cnblogs.com/bigbrox/p/11316059.html
Copyright © 2011-2022 走看看