Poj 1094 Sorting It All Out——拓扑排序

来源:互联网 发布:淘宝几单一颗心 编辑:程序博客网 时间:2024/04/25 16:07

题目链接:

http://poj.org/problem?id=1094


题目大意:

这个题目的难点就在于题目意思的理解。

有n个大写字母,并且告诉这n个大写字母的大小关系,要你对这n个大写字母进行排序。


解题思路:

但是,这个题目并不是等所有的输入结束之后判断,而是一边输入一边进行判断。

每次输入一组字母的关系之后,我们就需要更新原来的图。


如果原来的图已经能够确定一个排序或者已经能够确定不能排序,那么就不用进行排序了。

如果原来的图不能确定一个排序,那么进行一次拓扑排序。


拓扑排序之后,如果出现了环,则说明找不到这样的一个拓扑排序。

如果这个时候已经可以将所有的字母排序了,那么余下的那些字母关系我们不需要再理会。

但是最后一定要记得把所有的输入都读进去。


源代码:

#include<stdio.h>#include<stdlib.h>#include<string>#include<string.h>#include<math.h>#include<cmath>#include<vector>#include<map>#include<iostream>#include<algorithm>using namespace std;int s[27][27];int key[27];int d[27];     //记录下每个点的度数int d1[27];    //暂时存储每个点的度数int flag,n,m,ans;void top_order()        //拓扑排序{    int i,j,k,cnt,cc;    cc=0;    for(i=1;i<=n;i++)    {        d1[i]=d[i];//        printf("%d\n",d1[i]);    }    for(i=1;i<=n;i++)   //寻找第1个点    {        cnt=0;        for(j=1;j<=n;j++)        {            if(d1[j]==0)            {                cnt++;                k=j;            }        }        if(cnt==0)              //没有解的情况        {            flag=1;            break;        }        if(cnt==1)  cc++;        d1[k]=-1;        key[i]=k;        for(j=1;j<=n;j++)            if(s[k][j])                d1[j]--;    }    if(cc==n)   flag=2;    return;}int main(){    freopen("in.txt","r",stdin);    int a,b,i,j;    char x,y;    while(scanf("%d%d",&n,&m)==2 && n+m)    {        getchar();        memset(s,0,sizeof(s));        memset(d,0,sizeof(d));        memset(key,0,sizeof(key));        ans=0;        flag=0;         //初始化为2,是因为没有输入的时候是不能确定排序的        for(i=1;i<=m;i++)          //每输入一组解就对该图进行一次拓扑排序,如果出现环或者排序已经出来了,则可以输出最后结果        {            scanf("%c<%c",&x,&y);            a=x-64;            b=y-64;            getchar();            if(a==b)        //去掉自环的情况                flag=1;            if(!s[a][b])    //可能出现重边            {                s[a][b]=1;                d[b]++;            }            if(flag==0)         //前一状态的图还不能确定一个排序,进行进一步的排序                top_order();            if(flag==1)            {                if(!ans)    ans=i;                continue;       //出现了环,不往下做,但是数据必须输入完            }            if(flag==2)            {                if(!ans)    ans=i;                continue;       //已经能得到一个唯一的拓扑排序了,不往下做了            }        }        if(flag==1)     //出现了环的情况        {            printf("Inconsistency found after %d relations.\n",ans);        }        else if(flag==0)    //有多种解的情况        {            printf("Sorted sequence cannot be determined.\n");        }        else if(flag==2)    //只有唯一解的情况        {            printf("Sorted sequence determined after %d relations: ",ans);            for(i=1;i<=n;i++)                printf("%c",key[i]+64);            printf(".\n");        }    }    return 0;}

原创粉丝点击