判断给定图是否存在合法拓扑序列

 

                       数据结构实验之图论十:判断给定图是否存在合法拓扑序列

                                                                 Time Limit: 1000 ms Memory Limit: 65536 KiB

Problem Description

 给定一个有向图,判断该有向图是否存在一个合法的拓扑序列。

Input

 输入包含多组,每组格式如下。

第一行包含两个整数n,m,分别代表该有向图的顶点数和边数。(n<=10)

后面m行每行两个整数a b,表示从a到b有一条有向边。

 

Output

 若给定有向图存在合法拓扑序列,则输出YES;否则输出NO。

 

Sample Input

1 0
2 2
1 2
2 1

Sample Output

YES
NO

http://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Contest/contestproblem/cid/2720/pid/2140

 拓扑序列,即有向图无环。

每次找一个入度为零的点,将所有和它相连的点的入度减一(删除相连的边),重复此步骤(有n个点,每次选择一个入度为0的点,进行n次)。如果这时还有入度不为零的点,证明有环,输出NO,反之输出YES。

#include
#include

int map[20][20],flag[20],du[20];//边,每个节点是否已被删去,每个节点的入度

int main()
{
    int i,j,m,n,v,u,num,k;
    while(scanf("%d %d",&n, &m)!= EOF)//n个点,m条边
    {
        memset(map,0,sizeof(map));
        memset(du,0,sizeof(du));
        memset(flag,0,sizeof(flag));

        if(m == 0)//边的个数为0,一定是拓扑序列
        {
            printf("YES\n");
            continue;
        }

        for(i = 0; i < m; i ++)
        {
            scanf("%d %d",&u, &v);
            map[u][v] = 1;
            du[v] ++;//此边的入度+1
        }

        num = 0;

        for(i = 1; i <= n; i ++)//总共要删n个点,循环n次
        {
            for(j = 1; j <= n; j ++)
            {
                if(!du[j]&&!flag[j])//如果此点没有被删除,而且入度为0
                {

                    flag[j] = 1;//删除此点
                    for(k = 1; k <= n; k ++)//并把此点指向的其他点的入度减一
                    {
                        if(map[j][k])
                            du[k] --;
                    }
                    num ++;//个数+1
                    break;//跳出此循环,进行大循环,找下一个入度为0得点
                }

            }
        }
        if(num == n)//如果成功删掉了n个点,那就是拓扑序列
            printf("YES\n");
        else
            printf("NO\n");
    }

    return 0;
}

 

你可能感兴趣的:(判断给定图是否存在合法拓扑序列)