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

    将DAG图转化为顺序排列的形式

    可应用于DP求最长路、基于两两优劣关系求排名等题型。

    前向星版代码:

    #include <iostream>
    #include <queue>
    #include <cstdio>
    #include <vector>
    #define N 505
    using namespace std;
    int n,m,sum,cnt,flag;
    int deg[N];
    int head[N];
    struct Node
    {
        int v,next;
    };
    struct cmp
    {
        bool operator()(int a,int b)
        {
            return a>b;
        }
    };
    Node edge[N<<1];
    void print(int num)
    {
        if(flag==0)
            printf("%d",num),flag=1;
        else
            printf(" %d",num);
    }
    void topoSort(int n)
    {
        priority_queue<int,vector<int>,cmp> q;
        for(int i=1;i<=n;i++)
            if(deg[i]==0)
                q.push(i),deg[i]--;
        while (!q.empty())
        {
            int u = q.top();
            q.pop(), print(u);
            sum--;
            for (int i = head[u]; i != -1; i = edge[i].next)
            {
                Node e = edge[i];
                deg[e.v]--;
                if (deg[e.v] == 0) q.push(e.v), deg[e.v]--;
                
            }
        }
    }
    void ini()
    {
        for(int i=1;i<=n;i++)
            deg[i]=0,head[i]=-1,flag=0;
        cnt=0,sum=n;
    }
    void add(int u,int v)
    {
        deg[v]++;
        edge[cnt].v=v;
        edge[cnt].next=head[u];
        head[u]=cnt++;
    }
    int main(int argc, const char * argv[]) {
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            int a,b;
            ini();
            for(int i=0;i<m;i++)
                scanf("%d%d",&a,&b),add(a,b);
            topoSort(n);
            puts("");
        }
        return 0;
    }

    邻接表版代码:

    #include <iostream>
    #include <queue>
    #include <cstdio>
    #include <vector>
    #define N 505
    using namespace std;
    int n,m,sum,cnt,flag;
    int deg[N];
    vector<int> g[N];
    struct cmp
    {
        bool operator()(int a,int b)
        {
            return a>b;
        }
    };
    void print(int num)
    {
        if(flag==0)
            printf("%d",num),flag=1;
        else
            printf(" %d",num);
    }
    void topoSort(int n)
    {
        priority_queue<int,vector<int>,cmp> q;
        for(int i=1;i<=n;i++)
            if(deg[i]==0)
                q.push(i),deg[i]--;
        while(!q.empty())
        {
            //if(q.size()>1) 可用于判断是否充分排序。
            //如果有多个入度为0的同时入队,说明他们之间没有明确的排序条件。
            int u=q.top();
            q.pop(),print(u);
            sum--;//可用于判断是否有冲突,如果有冲突,就会导致两者或者已上的节点入度无法降为0
            for(int i=0;i<g[u].size();i++)
            {
                int e=g[u][i];
                deg[e]--;
                if (deg[e.v] == 0) q.push(e.v), deg[e.v]--;
            }
            
        }
    }
    void ini()
    {
        for(int i=0;i<=n;i++)
            deg[i]=0,flag=0,g[i].clear();
        cnt=0,sum=n;
    }
    void add(int u,int v)
    {
        deg[v]++;
        g[u].push_back(v);
    }
    int main(int argc, const char * argv[]) {
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            int a,b;
            ini();
            for(int i=0;i<m;i++)
                scanf("%d%d",&a,&b),add(a,b);
            topoSort(n);
            puts("");
        }
        return 0;
    }
  • 相关阅读:
    linux ss 网络状态工具
    如何安装最新版本的memcached
    如何通过XShell传输文件
    mysql主从复制原理
    聊聊IO多路复用之select、poll、epoll详解
    聊聊 Linux 中的五种 IO 模型
    pytorch中使用cuda扩展
    pytorch中调用C进行扩展
    双线性插值
    python中的装饰器
  • 原文地址:https://www.cnblogs.com/LukeStepByStep/p/5957001.html
Copyright © 2011-2022 走看看