zoukankan      html  css  js  c++  java
  • #拓扑序列 学习心得 ~2020.08.13

    Acwing 848. 有向图的拓扑序列

    1、拓扑定义: 若一个由图中所有点构成的序列A满足:对于图中的每条边(x, y),x在A中都出现在y之前,则称A是该图的一个拓扑序列。
    通俗来说:当这个图的所有点排成一个序列时, 所有边的箭头都是往后指的。
    所以,拓扑序不是唯一的。
    
    2、有向无环图一定有拓扑序列。所以 有向无环图 又称 拓扑图。
      有向无环图一定至少存在一个 入度 为0 的点;
     (反证:假如所有的入度都不是0,那么就可以无穷尽地找下去, 会找到n + 1 个点, 但是只有n 个点, 所以有两个点是一样的。)
    
    3、拓扑思路:
    宽搜;{
    	*1定义队列q;
    	*2while q 不空{
    	*3		取队头 t;
    	*4		枚举t所有的出边t -> j;
    	*5		取得这条边的终点 j;
    	*6		删掉t -> j这条边,也就是取消 j 的一个入度,即 d[j] - - ; 
    	*7		if( d[j] == 0)说明 没有点可以到 j 了;
    	*8		j -> q;j 入队。  		
    	}	
    	*9return ~;按要求返回;
    }
    
    例题

    链接

    	给定一个n个点m条边的有向图,点的编号是1到n,图中可能存在重边和自环。
    
    请输出任意一个该有向图的拓扑序列,如果拓扑序列不存在,则输出-1。
    
    若一个由图中所有点构成的序列A满足:对于图中的每条边(x, y),x在A中都出现在y之前,则称A是该图的一个拓扑序列。
    
    输入格式
    第一行包含两个整数n和m
    
    接下来m行,每行包含两个整数x和y,表示存在一条从点x到点y的有向边(x, y)。
    
    输出格式
    共一行,如果存在拓扑序列,则输出拓扑序列。
    
    否则输出-1。
    
    数据范围
    1≤n,m≤105
    输入样例:
    3 3
    1 2
    2 3
    1 3
    输出样例:
    1 2 3
    
    对应模板
    #include<bits/stdc++.h>
    using namespace std;
    const int N = 100010;
    int n, m;
    int h[N], e[N], ne[N], idx;
    int q[N], d[N];
    
    void add( int a, int b){
        e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
    }
    bool topsort(){
        int hh = 0, tt = -1;
        
        for(int i = 1; i <= n; i ++)				/* *1 */
            if(!d[i])
                q[++ tt] = i;
        
        while(hh <= tt){							/* *2 */
            int t = q[hh ++];						/* *3 */
            for(int i = h[t]; i != -1; i = ne[i]){  /* *4 */
                int j = e[i];						/* *5 */
                d[j] --;							/* *6 */
                if(d[j] == 0)						/* *7 */
                    q[++tt] = j;					/* *8 */
            }
        }
        return tt == n - 1;							/* *9 */
    }
    int main(){
        cin >> n >> m;
        memset(h, -1, sizeof h);
        for(int i =0; i < m; i ++){
            int a, b;
            cin >> a >> b;
            add(a, b);
            d[b] ++;
        }
        if(topsort()){
            for(int i = 0; i <n; i ++)
                cout << q[i] << " ";
        }
        else cout << "-1" <<endl;
        return 0;
    }
    

    ————————————————————————————————————

  • 相关阅读:
    文本框设置只读,后台可获取
    div 在同一行的 CSS处理
    在标签中添加属性
    (转)如何使用SignalTap II觀察reg與wire值? (SOC) (Verilog) (Quartus II) (SignalTap II)
    (转)如何使用ModelSim對Megafunction或LPM作仿真? (SOC) (MegaCore) (ModelSim)
    (笔记)TSL235新型光感器件强烈推荐使用
    (转)如何增加SignalTap II能觀察的reg與wire數量? (SOC) (Quartus II) (SignalTap II)
    (转) 如何將10進位轉2進位? (C/C++) (C)
    (转)如何使用ModelSim作前仿真與後仿真? (SOC) (Quartus II) (ModelSim)
    (笔记)关于LM3S片内FLASH编程的一点建议
  • 原文地址:https://www.cnblogs.com/yuanyulin/p/14026760.html
Copyright © 2011-2022 走看看