码迷,mamicode.com
首页 > 编程语言 > 详细

拓扑排序

时间:2016-10-13 17:07:01      阅读:217      评论:0      收藏:0      [点我收藏+]

标签:

将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]--;
        }
        for(int i=1;i<=n;i++)
            if(deg[i]==0)
                q.push(i),deg[i]--;
    }
}
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]--;
        }
        for(int i=1;i<=n;i++)
            if(deg[i]==0)
                q.push(i),deg[i]--;
    }
}
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;
}

 

拓扑排序

标签:

原文地址:http://www.cnblogs.com/LukeStepByStep/p/5957001.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!