【POJ 1094】 Sorting It All Out (拓扑排序)

来源:互联网 发布:java三大框架做什么的 编辑:程序博客网 时间:2024/06/05 00:57

传送门

POJ1094 Sorting It All Out

I think

    题意:给定n个字母,m个限制。对于以下三种情况,分别输出。
    1)有唯一拓扑序,输出在输入了第几条边后可确定。
    2)存在环,输出在输入了第几条边后有环。
    3)有多种拓扑序,输出特定字符串。(所有边输入完才能够判断)
    思路:每输入一条边跑一次拓扑,任意拓扑过程中若存在环,则入栈元素数 < N,任意时刻若栈中超过一个元素,则暂不能确定顺序。 若可以确定顺序且无环,则添加完当前边确定唯一拓扑序。

Code

#include<cstdio>using namespace std;const int sm = 28;const int sn = sm*sm>>1;int N,M,tot;int Rd[sm];int to[sn],nxt[sn],hd[sm];char ch[5];void Swap(int &x,int &y) { int t=x;x=y;y=t; }void Add(int u,int v) {    to[++tot]=v,nxt[tot]=hd[u],hd[u]=tot,Rd[v]++;}int rd[sm],Stk[sm],rec[sm];int Topsort() {    int t,cnt=0,fl=0,top=0;    for(int i=1;i<=N;++i) {        rd[i]=Rd[i];        if(rd[i]==0)            Stk[++top]=i;    }    while(top) {        t=Stk[top--];         rec[++cnt]=t;        if(top) fl=1;        for(int i=hd[t];i;i=nxt[i]) {            rd[to[i]]--;            if(rd[to[i]]==0)                 Stk[++top]=to[i];        }    }    if(cnt!=N) return 2;    if(!fl) return 1;     return 3;}int main() {    int p,q,flag; bool Mk;    while(scanf("%d%d",&N,&M)!=EOF) {        if(!N&&!M) break;         Mk=0,tot=0;        for(int i=1;i<=N;++i) Rd[i]=hd[i]=0;        for(int i=1;i<=M;++i) {            scanf("%s",ch);            p=ch[0]-'A'+1,q=ch[2]-'A'+1;            if(ch[1]=='>') Swap(p,q);            Add(p,q);            if(Mk) continue;            flag=Topsort();            if(flag==1) {                printf("Sorted sequence determined after %d relations: ",i);                for(int i=1;i<=N;++i) printf("%c",rec[i]+'A'-1);                printf(".\n"); Mk=1;            }            if(flag==2) {                printf("Inconsistency found after %d relations.\n",i);                Mk=1;            }        }        if(!Mk) printf("Sorted sequence cannot be determined.\n");    }    return 0;}