POJ 1094 Sorting It All Out (拓扑排序,判断序列是否唯一,图是否有环)

题意:给出n个字符,m对关系,让你输出三种情况:
     1.若到第k行时,能判断出唯一的拓扑序列,则输出:
         Sorted sequence determined after k relations: 序列
     2.若到第k行,出现环,则输出:
         Inconsistency found after k relations.
     3.若直到m行后,仍判断不出唯一的拓扑序列,则输出:
         Sorted sequence cannot be determined.
思路:每读取一行,就进行一次拓扑排序,为防止影响之后的拓扑排序,拓扑排序时用的入度数组为into2。
      如果拓扑排序能得出唯一的序列,即为第一种情况,之后只要直接读取数据,不必操作。
      如果拓扑排序时不存在入度为0的节点,则为第二种情况,之后只要直接读取数据,不必操作。
      如果拓扑排序时有多个入度为0的节点,则继续读取数据再操作,直至读完m行。

 

#include <iostream>
#include <stdio.h>
#include <cstring>
#include <algorithm>

using namespace std;
int into[30],into2[30];  //存储节点的入度数
int edge[30][30];
int ans[30],idx; //存储拓扑序列
int row,n,m; //row存储最后唯一判断出拓扑序列或者出现环的行数

int topo(int n){
    int i,j=0,k,t=0,mark=1;
    while(j<n){
        t=0;
        //统计入度为0的节点个数
        for(i=0;i<n;i++){
            if(into2[i]==0){
                t++;
                if(t==1)
                    k=i;
            }
        }
        //当入度为0的点大于1个时,也存在有环的情况!所以当t>1时,不能直接return 0,也要继续拓扑下去,看是否有当t=0的情况,
        if(t>1){
            mark=0;
        }
        if(t==0)
            return -1;  //没找到入度为0的点,有环存在
        ans[j++]=k;
        into2[k]=-1;
        for(i=0;i<n;i++){
            if(edge[k][i])
                into2[i]--;
        }
    }
    return mark;
}
int main()
{
    char a,b,c;
    char str[10];
    int flag,tmp,u,v;
    while(scanf("%d%d",&n,&m)!=EOF){
        if(n==0 && m==0)
            break;
        memset(edge,0,sizeof(edge));
        memset(into,0,sizeof(into));
        memset(into2,0,sizeof(into2));
        memset(vis,0,sizeof(vis));
        idx=0;
        flag=0;//flag=1为第一种情况,=-1为第二种情况,=0为第三种情况
        for(int i=1;i<=m;i++){
            scanf("%s",str);
            a=str[0];b=str[2];
            if(flag==1 || flag==-1)
                continue;
            u=a-'A';v=b-'A';
            edge[u][v]=1;
            into[v]++;
            into2[v]++;
            tmp=topo(n);
            if(tmp==-1){
                row=i;
                flag=-1;  //有环,即出现矛盾
            }
            else if(tmp==0){
                for(int q=0;q<30;q++)
                    into2[q]=into[q];
                continue;
            }
            else{
                row=i;
                flag=1;
            }
        }
        if(flag==1){
            printf("Sorted sequence determined after %d relations: ",row);
            for(int i=0;i<n;i++)
                printf("%c",ans[i]+'A');
            printf(".\n");
        }
        else if(flag==-1){
            printf("Inconsistency found after %d relations.\n",row);
        }
        else{
            printf("Sorted sequence cannot be determined.\n");
        }

    }
    return 0;
}

 

posted @ 2013-10-15 20:42  辰曦~文若  阅读(639)  评论(0编辑  收藏  举报