• POJ 1094 Sorting It All Out


    Sorting It All Out
    Time Limit: 1000MS   Memory Limit: 10000K
    Total Submissions: 23082   Accepted: 7978

    Description

    An ascending sorted sequence of distinct values is one in which some form of a less-than operator is used to order the elements from smallest to largest. For example, the sorted sequence A, B, C, D implies that A < B, B < C and C < D. in this problem, we will give you a set of relations of the form A < B and ask you to determine whether a sorted order has been specified or not.

    Input

    Input consists of multiple problem instances. Each instance starts with a line containing two positive integers n and m. the first value indicated the number of objects to sort, where 2 <= n <= 26. The objects to be sorted will be the first n characters of the uppercase alphabet. The second value m indicates the number of relations of the form A < B which will be given in this problem instance. Next will be m lines, each containing one such relation consisting of three characters: an uppercase letter, the character "<" and a second uppercase letter. No letter will be outside the range of the first n letters of the alphabet. Values of n = m = 0 indicate end of input.

    Output

    For each problem instance, output consists of one line. This line should be one of the following three: 

    Sorted sequence determined after xxx relations: yyy...y. 
    Sorted sequence cannot be determined. 
    Inconsistency found after xxx relations. 

    where xxx is the number of relations processed at the time either a sorted sequence is determined or an inconsistency is found, whichever comes first, and yyy...y is the sorted, ascending sequence. 

    Sample Input

    4 6
    A<B
    A<C
    B<C
    C<D
    B<D
    A<B
    3 2
    A<B
    B<A
    26 1
    A<Z
    0 0
    

    Sample Output

    Sorted sequence determined after 4 relations: ABCD.
    Inconsistency found after 2 relations.
    Sorted sequence cannot be determined.

    Source

    题目大意:
      给出一些字母和它们之间的偏序关系,让你来判断通过这些关系是否能构成唯一的升序序列。如果能,输出这个序列,并输出是通过前多少关系得出的(即使之后的关系引出矛盾也不必理会)。如果存在矛盾,则输出前多少项出现的矛盾的。如果输入完仍无法得出唯一关系,输出相关信息。
    题目算法:
      拓扑排序。
      拓扑排序:若G包含有向边(U,V),则在序列中U出现在V之前,即该序列使得图中所有有向边均从左指向右。如果图是有回路的,就不存在这样的序列。
      首先选择一个无前驱的顶点(即入度为0的顶点,图中至少应该有一个这样的顶点,否则肯定存在回路),然后从图中移去该顶点以及由其发出的所有有向边,如果图中还存在无前驱的顶点,则重复上述操作,直到操作无法进行。如果图不为空,说明图中存在回路,无法进行拓扑排序;否则移出的顶点的顺序就是对该图的一个拓扑排序。
    具体思路:
      每输入一组偏序关系进行一次拓扑排序。
      如果存在回路,输出矛盾。
      在不存在回路的基础上,判断每次入度为0的点是否唯一,只有保证每次只有一个点入度为0,才能保证最终的序列唯一。
    注意:如果对于某一次输入已经能确定序列矛盾或者序列完全有序,则可以忽略后面的输入。

    当入度为0的定点大于1时,直接return了,但之后可能出现回路即矛盾的情况。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<stack>
    
    using namespace std;
    
    int n,m,indeg[30],vis[30];
    vector<int> vt[30];
    char res[30];
    
    int TopoSort(){
        stack<int> st;
        int flag=1;
        for(int i=0;i<n;i++){
            vis[i]=indeg[i];
            if(indeg[i]==0)
                st.push(i);
        }
        if(st.size()>1)
            flag=0;
        int cnt=0;
        while(!st.empty()){
            int u=st.top();
            st.pop();
            res[cnt++]=(char)u+'A';
            for(int i=0;i<vt[u].size();i++)
                if(--vis[vt[u][i]]==0)
                    st.push(vt[u][i]);
            if(st.size()>1)
                flag=0;
        }
        res[cnt]='\0';
        for(int i=0;i<n;i++)
            if(vis[i])
                return -1;
        return flag && (cnt==n);
    }
    
    int main(){
    
        //freopen("input.txt","r",stdin);
    
        char str[5];
        int tag,flag,ans;
        while(~scanf("%d%d",&n,&m)){
            if(n==0 && m==0)
                break;
            memset(indeg,0,sizeof(indeg));
            for(int i=0;i<n;i++)
                vt[i].clear();
            ans=tag=0;
            for(int i=1;i<=m;i++){
                scanf("%s",str);
                vt[str[0]-'A'].push_back(str[2]-'A');
                indeg[str[2]-'A']++;
                if(tag==0){
                    flag=TopoSort();
                    if(flag==-1){
                        ans=i;
                        tag=-1;
                    }
                    if(flag==1){
                        ans=i;
                        tag=1;
                    }
                }
            }
            if(tag==1)
                printf("Sorted sequence determined after %d relations: %s.\n",ans,res);
            else if(tag==-1)
                 printf("Inconsistency found after %d relations.\n",ans);
            else if(tag==0)
                 printf("Sorted sequence cannot be determined.\n");
        }
        return 0;
    }

    一些练习:http://www.cnblogs.com/372465774y/category/424141.html

     1 #include<iostream>
     2 #include<string>
     3 #include<cstdio>
     4 #include<cstring>
     5 
     6 using namespace std;
     7 
     8 int deg[30],d[30],g[30][30],res[30];
     9 int n,m;
    10 
    11 int Topo(string str){
    12     int x=str[0]-'A';
    13     int y=str[2]-'A';
    14     if(g[x][y]==0){
    15         g[x][y]=1;
    16         d[y]++;
    17     }
    18     for(int i=0;i<n;i++)
    19         deg[i]=d[i];
    20     int flag=1,len=0,tmp,cnt;
    21     for(int i=0;i<n;i++){
    22         cnt=0;
    23         for(int j=0;j<n;j++)
    24             if(deg[j]==0){
    25                 tmp=j;
    26                 cnt++;
    27             }
    28         if(cnt==0)
    29             return -1;
    30         else if(cnt>1)      //这里不直接return 0;因为之后可能出现回路
    31             flag=0;
    32         deg[tmp]--;
    33         res[len++]=tmp;
    34         for(int j=0;j<n;j++)
    35             if(g[tmp][j]==1)
    36                 deg[j]--;
    37     }
    38     return flag;
    39 }
    40 
    41 void Solve(){
    42     string str;
    43     int flag=1;
    44     for(int i=0;i<m;i++){
    45         cin>>str;
    46         if(flag){
    47             int tmp=Topo(str);
    48             if(tmp==1){
    49                 cout<<"Sorted sequence determined after "<<i+1<<" relations: ";
    50                 for(int j=0;j<n;j++)
    51                     cout<<char(res[j]+'A');
    52                 cout<<"."<<endl;
    53                 flag=0;
    54             }else if(tmp==-1){
    55                 cout<<"Inconsistency found after "<<i+1<<" relations."<<endl;
    56                 flag=0;
    57             }
    58         }
    59     }
    60     if(flag)
    61         cout<<"Sorted sequence cannot be determined."<<endl;
    62 }
    63 
    64 int main(){
    65 
    66     //freopen("input.txt","r",stdin);
    67 
    68     string str;
    69     while(scanf("%d%d",&n,&m)){
    70         if(n==0 && m==0)
    71             break;
    72         if(n-1>m){
    73             for(int i=0;i<m;i++)
    74                 cin>>str;
    75             cout<<"Sorted sequence cannot be determined."<<endl;
    76             continue;
    77         }
    78         memset(g,0,sizeof(g));
    79         memset(d,0,sizeof(d));
    80         Solve();
    81     }
    82     return 0;
    83 }
  • 相关阅读:
    iOS多线程与网络开发之NSURLCache
    NEFU 117-素数个数的位数(素数定理)
    UISegmentedControl 的使用
    C++使用ADO存取图片
    王立平-- Swift
    浮生猫绘——落入平一的精灵
    BZOJ 1692: [Usaco2007 Dec]队列变换 [后缀数组 贪心]
    POJ2774 Long Long Message [后缀数组]
    BZOJ 2119: 股市的预测 [后缀数组 ST表]
    BZOJ 1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 [后缀数组]
  • 原文地址:https://www.cnblogs.com/jackge/p/3016381.html
Copyright © 2020-2023  润新知