zoukankan      html  css  js  c++  java
  • 图论:拓扑排序

    把一个图的所有节点进行排序,是的每一条有向边(u,v)所对应的u都排在v的前面

    如果一个有向图的拓扑序列不存在,那么它就不是一个DAG

    (DAG的最短路可以用动态规划方法求出,以后再介绍)

    好久没有参考刘汝佳的代码了。。

    int n,m,t;
    int g[maxn][maxn],c[maxn],topo[maxn];

    n个点m条边和临时变量t

    g是邻接矩阵,对于一个图来说,我们一般是用邻接表来存的,这里直接改成邻接表即可,在邻接表里记录一个每一条边的u节点,这样方便遍历

    c数组是用来判断当前点的状态的数组,0表示下标位置及其子孙位置没有进行过拓扑排序,1表示下标位置及其子孙位置进行过拓扑排序,然后-1表示当前节点的访问位于函数调用栈

    topo是拓扑序列

    bool dfs(int u)
    {
        c[u]=-1;
        for(int v=1;v<=n;v++)
        if(g[u][v])
        {
            if(c[v]<0) return false;
            else if(!c[v]) dfs(v);
        }
        c[u]=1;topo[t--]=u;
        return true;
    }

    函数的意义还是很明显的,明白了c数组的含义不难理解这个函数

    bool toposort()
    {
        t=n;
        memset(c,0,sizeof(c));
        for(int u=1;u<=n;u++)
        if(!c[u])if(!dfs(u)) return false;
        return true;
    }

    每个点均调用一次dfs,保证所有点都出现在序列里面

    下面给出完整的实现:

     1 #include<cstdio>
     2 #include<cstring>
     3 const int maxn=1005;
     4 int n,m,t;
     5 int g[maxn][maxn],c[maxn],topo[maxn];
     6 bool dfs(int u)
     7 {
     8     c[u]=-1;
     9     for(int v=1;v<=n;v++)
    10     if(g[u][v])
    11     {
    12         if(c[v]<0) return false;
    13         else if(!c[v]) dfs(v);
    14     }
    15     c[u]=1;topo[t--]=u;
    16     return true;
    17 }
    18 bool toposort()
    19 {
    20     t=n;
    21     memset(c,0,sizeof(c));
    22     for(int u=1;u<=n;u++)
    23     if(!c[u])if(!dfs(u)) return false;
    24     return true;
    25 }
    26 int main()
    27 {
    28     while(scanf("%d%d",&n,&m)==2&&n)
    29     {
    30         memset(g,0,sizeof(g));
    31         for(int i=1;i<=m;i++){int u,v;scanf("%d%d",&u,&v);g[u][v]=1;}
    32         if(toposort()){for(int i=1;i<=n;i++) printf("%d ",topo[i]);}
    33         else printf("No");
    34         printf("
    ");
    35     }
    36     return 0;
    37 }

    拓扑排序是后续很多知识点的一个前置技能,一定要深刻掌握

  • 相关阅读:
    在vs2010里使用EF4.3的Code First个人使用笔记
    如何充分利用C#匿名方法的平台优势(转)
    打开Microsoft SQL Server Management Studio 2005非常慢,特别慢的原因
    PowerShell msbuild
    很久没写了
    第一篇博客,逗大家一笑
    以编程方式调用按钮1(button1)的 Click 事件
    VS2010删除已安装的联机模板
    创建和分享你的Visual Studio color
    异步获取CMD命令行输出内容
  • 原文地址:https://www.cnblogs.com/aininot260/p/9388179.html
Copyright © 2011-2022 走看看