hdu1285(拓扑排序)

来源:互联网 发布:js 字符串日期格式化 编辑:程序博客网 时间:2024/05/18 06:48

题目链接:确定比赛名次

题目分析:若P1赢了P2,则在连一条边P1-->p2,对所有结点排序,求得一个序列,使得每一条有向边(u, v)对应的u都排在v的前面

方法一:

dfs,白书上讲的方法,但该方法不能保证输入的顺序
vis[u]=0表示从来没有访问过(从来没有调用过dfs(u));

vis[u]=1表示已经访问过,并且还递归访问过它的所有子孙(即dfs(u)曾被调用过,并已返回);这表示u已经包含在一个拓扑排序当中

c[u]=-1表示正在访问(即递归调用dfs(u)正在栈帧中,尚未返回),这表明有一个环,不满足拓扑排序,返回一个错误

#include <stdio.h>#include <memory.h>const int maxn=500+5;int n,g[maxn][maxn],vis[maxn],st[maxn],cnt;void init(){    cnt=n;    memset(g,0,sizeof(g));    memset(vis,0,sizeof(vis));}bool dfs(int u){    vis[u]=-1;    for(int v=1;v<=n;v++){        if(g[u][v]){            if(vis[v]==-1)return false;            if(!vis[v]&&!dfs(v))return false;        }    }    vis[u]=1;    st[--cnt]=u;    return true;}bool toposort(){    for(int u=1;u<=n;u++){        if(!vis[u])            if(!dfs(u))return false;    }    return true;}int main(){    freopen("in.txt","r",stdin);   int m,p1,p2;   while(scanf("%d %d",&n,&m)!=EOF){        init();        while(m--){            scanf("%d %d",&p1,&p2);            g[p1][p2]=1;        }        if(toposort()){            for(int i=0;i<n-1;i++)printf("%d ",st[i]);            printf("%d\n",st[n-1]);        }   }   return 0;}


方法二:

 (1)从有向图中选择一个没有前驱(即入度为0)的顶点并且输出它.
 (2)从网中删去该顶点,并且删去从该顶点发出的全部有向边.
  (3)重复上述两步,直到剩余的网中不再存在没有前趋的顶点为止.

代码:

#include <stdio.h>#include <memory.h>const int maxn=500+5;int n,deg[maxn],st[maxn],cnt;bool g[maxn][maxn];void init(){    cnt=n;    memset(g,0,sizeof(g));    memset(deg,0,sizeof(deg));}void toposort(){    int cur;    for(int i=0;i<n;i++){        for(int u=1;u<=n;u++){            if(!deg[u]){                cur=u;                deg[u]--;                st[i]=cur;                break;            }        }        for(int v=1;v<=n;v++){            if(g[cur][v]){                g[cur][v]=false;                deg[v]--;            }        }    }}int main(){    //freopen("in.txt","r",stdin);    int m,p1,p2;    while(scanf("%d %d",&n,&m)!=EOF){        init();        while(m--){            scanf("%d %d",&p1,&p2);            if(!g[p1][p2]){                g[p1][p2]=true;                deg[p2]++;            }        }        toposort();        for(int i=0;i<n-1;i++)printf("%d ",st[i]);        printf("%d\n",st[n-1]);   }   return 0;}


0 0
原创粉丝点击