uva 10305 拓扑排序

来源:互联网 发布:mac里的照片如何导出 编辑:程序博客网 时间:2024/06/05 11:41

题意:

假设有n个变量,还有m个二元组(u,v),分别表示变量u小于v。那么,所有变量从小到大排列起来应该是什么样子呢?例如,有4个变量a,b,c,d,若已知a<b,c<b,d<c,则这4个变量的排序可能是a<d<c<b。尽管还有其他可能(如d<a<c<b)你只需找出其中一个即可。

题解:

把每个变量看成一个点,”小于”关系看成有向边,则得到一个有向图。这样,我们的任务实际上是把一个图的所有结点排序,使得每一条有向边(u,v)对应的u都排在v的前面。在图论中,这个问题成为拓扑排序。

不难发现:如果图中存在有向环,则不存在拓扑排序,反之则存在。不包含有向环的有向图称为有向无环图。

代码:

#include <bits/stdc++.h>using namespace std;const int maxn = 1010;int c[maxn];int topo[maxn],t,n;int G[maxn][maxn];bool dfs(int u){    c[u]=-1;    for(int v=1;v<=n;v++)        if(G[u][v])    {        if(c[v]<0) return false;        else if(!c[v]&&!dfs(v)) return false;    }    c[u]=1;    topo[--t]=u;    return true;}bool toposort(){    t = n;    memset(c,0,sizeof(c));    for(int u=1;u<=n;u++)        if(!c[u])         if(!dfs(u)) return false;    return true;}int main(){    int m;    while(cin>>n>>m&&n+m)    {        memset(G,0,sizeof(G));        int u,v,i;        for(i=0;i<m;i++)        {            scanf("%d%d",&u,&v);            G[u][v]=1;        }        if(toposort())        {            for(i=0;i<n-1;i++)            {                printf("%d ",topo[i]);            }            printf("%d\n",topo[n-1]);        }    }    return 0;}
原创粉丝点击