首页 > 代码库 > POJ1094 Sorting It All Out

POJ1094 Sorting It All Out

POJ1094 Sorting It All Out

题目链接:http://poj.org/problem?id=1094

题意:这个题意确定是有点难懂,给你n个点,和m条边。问你在添加多少条边以后n个点的拓扑顺序是确定的,或者在添加多少条边以后出现了环,如果添加完所有的边,还存在有些点之间不可排序,就说明这些关系不足以排序的。

思路:一旦n个点的已经存在拓扑关系,或者出现环,就可以结束循环了,当添加完所有的点依然无法得到n个点之间的拓扑关系,或者环,就说明无法排序的。等于说加一条边,拓扑排序一次,这里注意,如果既出现环又出现点和点之间关系不确定的情况,我们还是认出现环,不出现环,出现了点和点之间关系不确定,我们才认关系不确定,剩下的就是已经排好序的。要确定他们的先后关系,不然在return的时候,可能会出错。基础的拓扑排序,只是多了一下判断和满足条件。理清他们的满足条件之间的关系,问题就是可以迎刃而解。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
const int N=26;
using namespace std;
struct d{
    char a,b,c;
}oj[100000];
int in[N],tin[N],ans[N],len;
vector<int>p[N];
int n,m,k;
int topo(){
    queue<int>q;
    k=0;
    memset(tin,0,sizeof(tin));
    for(int i=0;i<n;i++) if(!in[i]) {q.push(i);}
    int flag=0;
    len=0;
    while(!q.empty()){
        if(q.size()>1) flag=1;
        int t=q.front();q.pop();
        ans[k++]=t;
        for(int i=0;i<p[t].size();i++){
            int s=p[t][i];
            if(++tin[s]==in[s]){
                q.push(s);
            }
        } 
    }
    if(k<n) return -1; 
    else if(flag) return 0;
    return 1; 
}
int main(){
    while(cin>>n>>m&&(n+m)){
        for(int i=0;i<N;i++) p[i].clear();
        memset(in,0,sizeof(in));
        for(int i=0;i<m;i++){
            cin>>oj[i].a>>oj[i].b>>oj[i].c;
        }   
        int hl=-1,ul=-1;    
        for(int i=0;i<m;i++){
            int x=oj[i].a-A, y=oj[i].c-A;
            if(oj[i].b==>){
                p[x].push_back(y);
                in[y]++;
            }
            else if(oj[i].b==<){
                p[y].push_back(x);
                in[x]++;
            }
            int t=topo();
            if(t==1){
                hl=i+1;
                break;
            }
            else if(t==-1){
                 ul=i+1;
                 break;
            }
        }
        if(hl!=-1){
            cout<<"Sorted sequence determined after "<<hl<<" relations: ";
            for(int i=n-1;i>=0;i--) putchar(A+ans[i]);cout<<.;
        }
        else if(ul!=-1){
            cout<<"Inconsistency found after "<<ul<<" relations.";
        }
        else cout<<"Sorted sequence cannot be determined.";
        cout<<endl;
    }
    return 0;
}

判断是否出现环:拓扑排序中遍历的点的点数小于n,说明出现了环

判断是否出现无法比较的两个点:拓扑排序中的队列如果同时存在两个元素,说明这两个元素是无法比较的

POJ1094 Sorting It All Out