POJ1094 拓扑排序

Description:

有n个点和m个偏序关系,m个关系依次给出,若在某个关系给出后,拓扑序唯一确定,或是产生矛盾则直接输出相应信息。若在所有关系都给出后,拓扑序仍然不确定,则输出相应信息。

Input:

多组数组。

每组数据第一行给出n和m,之后m行每行为一个偏序关系。

n==0&&m==0结束

Output:

Sorted sequence determined after xxx relations: yyy...y.(唯一确定)

Sorted sequence cannot be determined.(矛盾)

Inconsistency found after xxx relations.(不确定)

yyyy为拓扑序答案,xxx指当前的关系序号。

分析:

核心问题在于对有向图进行拓扑排序且确定给定的条件是能唯一确定拓扑序的,还是矛盾的(有环),还是不确定。

可以用拓扑排序的队列方式确定,队列维护入度为0的节点,若当前队列中的节点不只一个,说明不确定。若没有入度为0点,并且排序尚未结束(代码中num!=n)则说明矛盾。否则若能一直排序完成,且队列在每次扩展前始终只有一个节点,则有唯一拓扑序。更加具体的分析,要看拓扑排序的Kahn算法。

更加具体一点:题目数组不大,可以每次读入一个关系就进行拓扑排序。值得注意的是。

1.

矛盾和多选,优先判断是否矛盾

2.

在矛盾之前如果有成功的,算是成功
(感谢discuss)

代码:

#include<iostream>
#include<string>
#include<cstring>
#include<vector>
#include<stack>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<sstream>
#include<cmath>
#include<iterator>
#include<bitset>
#include<stdio.h>
using namespace std;
#define _for(i,a,b) for(int i=(a);i<(b);++i)
#define _rep(i,a,b) for(int i=(a);i<=(b);++i)
typedef long long LL;
int readint() { int x; cin >> x; return x; }
const int INF = 1 << 30;
const int maxn = 105;

int n,m,ind[maxn],order[maxn];
vector<int>G[maxn];
int toposort(){
    int ind1[maxn];
    memcpy(ind1,ind,sizeof(ind));
    queue<int> Q;int num=0;
    for(int i=0;i<n;++i)if(!ind[i]){
        Q.push(i);
    }
    if(Q.empty())return -1;

    bool uncertain=false;

    while(Q.size()){
        if(Q.size()>1) uncertain=true;
        int u=Q.front();Q.pop();
        order[num++]=u;
        for(int i=0;i<G[u].size();++i){
            int v=G[u][i];
            if(--ind1[v]==0){
                Q.push(v);
            }
        }
    }
    //cout<<num<<endl;
    if(num!=n)return -1;
    if(uncertain)return 0;
    return 1;
}

int main()
{

   // freopen("C:\\Users\\admin\\Desktop\\in.txt", "r", stdin);
    //freopen("C:\\Users\\admin\\Desktop\\out.txt", "w", stdout);
    while(cin>>n>>m){
        if(n==0&&m==0)break;
       string s;
       for(int i=0;i<n;++i)G[i].clear();
       memset(ind,0,sizeof(ind));
       bool ok=false;
       for(int i=1;i<=m;++i){
            cin>>s;
            if(!ok){
                int u=s[0]-'A',v=s[2]-'A';
                G[u].push_back(v);
                ind[v]++;
                int flag=toposort();
                if(flag==-1){
                    printf("Inconsistency found after %d relations.\n",i);
                    ok=true;
                }
                else if(flag==1){
                    char ans[maxn]; for(int i=0;i<n;++i)ans[i]=order[i]+'A';ans[n]='\0';
                    printf("Sorted sequence determined after %d relations: %s.\n",i,ans);
                    ok=true;
                }
                else if(flag==0&&i==m){
                    printf("Sorted sequence cannot be determined.\n");
                }
            }
       }

    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/tomandjake_/article/details/80265329