UVA 10305 Ordering Tasks

来源:互联网 发布:大数据泄露 编辑:程序博客网 时间:2024/05/16 19:08

           题目链接

         这是拓扑排序的一道基础题,代码在《算法竞赛入门经典》P111,比着葫芦画瓢,但是其实质还是没有完全理解。

#include<cstdio>#include<cstring>using namespace std;int g[110][110],c[110],topo[110],t,m,n;int dfs(int u){    c[u]=-1;    for(int v=1; v<=m; v++)    {        if(g[u][v])        {            {                if(c[v]==-1)  return 0;//存在有向环,失败退出。                else if(!c[v]&&!dfs(v))  return 0;            }        }    }    c[u]=1;    topo[--t]=u;    return 1;}int toposort(){    for(int u=1; u<=m; u++)    {        if(!c[u])        {            if(!dfs(u))                return 0;        }    }    return 1;}int main(){    /*freopen("in.txt","r",stdin);*/    int a,b;    while(scanf("%d%d",&m,&n)!=EOF)    {        if(m==0&&n==0)  break;        t=m;        memset(g,0,sizeof(g));        memset(c,0,sizeof(c));        for(int i=1; i<=n; i++)        {            scanf("%d%d",&a,&b);            g[a][b]=1;        }        toposort();        printf("%d",topo[0]);        for(int i=1; i<m; i++)            printf(" %d",topo[i]);        putchar('\n');    }    return 0;}
            书中这样解释:数组C【i】=0表示没有访问过,=1表示已经访问过,并且递归访问了他的所有子孙,=-1表示正在访问。

           可以看出topo数组中的元素是倒着进入的, 自己单步跟踪了一下,void toposort() 中的  for(int u=1; u<=m; u++)   是从第一个数字即u=1开始,判断这个数字可以进入topo数组的条件是没有必须要排在u后面的数字,或者是需要排在u后面的数字已经bfs过了,即c[]=1;也就是int dfs(int u)这个函数,但是if(c[v]==-1)  return 0;这个有向环的判断还是不太理解呢。