拓扑排序(判断是否是有向无环图)

要进行拓扑排序之前,该图要是有向无环图。

排序方法:

1、从有向图中选取一个没有前驱的顶点,并输出之

;2、从有向图中删去此顶点以及所有以它为尾的弧;

3、重复上述两步,直至图空,或者图不空但找不到无前驱的顶点为止。

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
const int maxn=100001;
const int inf=1<<29;
int e,head[maxn],pnt[maxn],nxt[maxn];
int cnt_in[maxn],cnt_out[maxn];
bool vis[maxn];
int n,m,k;
void AddEdge(int u,int v)
{
    pnt[e]=v;nxt[e]=head[u];head[u]=e++;
}
int main()
{
    int tt;
    scanf("%d",&tt);
    while(tt--)
    {
        scanf("%d%d",&n,&m);
        e=0;
        memset(head,-1,sizeof(head));
        memset(cnt_in,0,sizeof(cnt_in));
        memset(cnt_out,0,sizeof(cnt_out));
        memset(vis,0,sizeof(vis));
        for(int i=0;i<m;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            AddEdge(u,v);
            cnt_out[u]++;
            cnt_in[v]++;
        }
        /*for(int i=1;i<=n;i++)
        {
            printf("%d :",i);
            printf("%d %d\n",cnt_in[i],cnt_out[i]);
        }*/
        int cnt=0;
        int kj[maxn];
        while(1)
        {
            int f=0;
            for(int u=1;u<=n;u++)
            {
                if(cnt_in[u]==0&&!vis[u])
                {
                    f=1;
                    for(int i=head[u];i!=-1;i=nxt[i])
                    {
                        cnt_in[pnt[i]]--;
                    }
                    kj[cnt++]=u;
                    vis[u]=1;
                }
            }
            if(cnt==n||f==0)
                break;
        }
        int k2=0;
        for(int i=1;i<=n;i++)//如果所有的数字的入度都为0,代表这是一个无环图。
            if(vis[i]==0)
             k2=1;
        if(k2==1)
        puts("Wrong");
        else
            puts("Correct");

    }
    return 0;
}

而拓扑排序 只要将上面的数组kj[]从小到大输出即可。

 for(int i=0;i<cnt;i++)
            printf(“%d “,kj[i]);

    原文作者:拓扑排序
    原文地址: https://blog.csdn.net/kjbu2/article/details/46127683
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞