zoukankan      html  css  js  c++  java
  • 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,说明出现了环

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

  • 相关阅读:
    message sent to deallocated instance
    将本地项目提交github
    WKWebView 初窥-JS交互探究
    抓包工具Charles的使用
    iOS hook delegate (一)
    Return
    控制方法只有相应权限才可执行
    如何模拟登陆添加了CSRF保护的网站
    HTTP客户端都应该支持的五个特性
    如何利用WebClient模拟登陆CSRF控制的网站
  • 原文地址:https://www.cnblogs.com/xiaowuga/p/7226638.html
Copyright © 2011-2022 走看看