拓扑排序

#include<bits/stdc++.h>
using namespace std;
int e[10][10];
int c[10];
stack<int> s;
int n,m;
bool dfs(int u)
{
    c[u]=-1;
    for(int v=1; v<=n; v++)
    {
        if(e[u][v]==1)
        {
            if(c[v]==-1)
                return false;
            if(c[v]==0 && !dfs(v))
                return false;
        }
    }
    c[u]=1;s.push(u);
    return true;
}
bool toposort()
{
    memset(c,0,sizeof(c));
    for(int i=1; i<=n; i++)
    {
        if(c[i]==0 && !dfs(i))
            return false;
    }
    return true;
}
int main()
{

    scanf("%d%d", &n, &m);
    for(int i=1; i<=m; i++)
    {
        int a,b;
        scanf("%d%d", &a, &b);
        e[a][b]=1;
    }
    if(toposort())
    {
        while(!s.empty())
        {
            printf("%d ", s.top());
            s.pop();
        }
    }
}

 

 

之前是紫书上看的,这个是算法进阶指南上的,感觉这个思路更加清晰容易,这个是用邻接表存有向图,如果a在b的前面那么a->b同时b的入度加一。拓扑排序就是先找入度为0的点,然后在广度优先遍历与这个点相邻的点,将它减去与x相邻的这个入度1之后看看是否为零,为零的话可取,最后判断数组a中是否有n个点,如果小于n的话是这个有向图中出现了环。

#include<bits/stdc++.h>
using namespace std;
int head[1005],ver[1005],nxt[1005],rudu[1005];
int tot=0;
int a[1005];
int cnt=0;
int n,m;
void add(int x,int y)
{
    ver[++tot]=y;
    rudu[y]++;
    nxt[tot]=head[x];
    head[x]=tot;
}

void topsort()
{
    queue<int> q;
    for(int i=1; i<=n; i++)
    {
        if(rudu[i]==0)
            q.push(i);
    }
    while(q.size())
    {
        int x=q.front();
        q.pop();
        a[++cnt]=x;
        for(int i=head[x]; i; i=nxt[i])
        {
            int y=ver[i];
            if(--rudu[y]==0)
                q.push(y);
        }
    }
}
int main()
{

    cin>>n>>m;
    for(int i=1; i<=m; i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        add(x,y);
    }
    topsort();
    if(cnt==n)
    {
        for(int i=1; i<=n; i++)
            printf("%d ",a[i]);
    }
    else
        printf("No");
}

 

posted @ 2018-11-22 15:58  paranoid。  阅读(160)  评论(0编辑  收藏  举报