zoukankan      html  css  js  c++  java
  • P1347 排序

    P1347 排序

    题目描述

    一个不同的值的升序排序数列指的是一个从左到右元素依次增大的序列,例如,一个有序的数列A,B,C,D 表示A<B,B<C,C<D。在这道题中,我们将给你一系列形如A<B的关系,并要求你判断是否能够根据这些关系确定这个数列的顺序。

    输入输出格式

    输入格式: 

    第一行有两个整数n,m,n表示需要排序的元素数量,2<=n<=26,第1到n个元素将用大写的A,B,C,D....表示。m表示将给出的形如A<B的关系的数量。

    接下来有m行,每行有3个字符,分别为一个大写字母,一个<符号,一个大写字母,表示两个元素之间的关系。

    输出格式:

    若根据前x个关系即可确定这n个元素的顺序yyy..y(如ABC),输出

    Sorted sequence determined after xxx relations: yyy...y.

    若根据前x个关系即发现存在矛盾(如A<B,B<C,C<A),输出

    Inconsistency found after 2 relations.

    若根据这m个关系无法确定这n个元素的顺序,输出

    Sorted sequence cannot be determined.

    (提示:确定n个元素的顺序后即可结束程序,可以不用考虑确定顺序之后出现矛盾的情况)

    输入输出样例

    输入样例#1: 
    4 6
    A<B
    A<C
    B<C
    C<D
    B<D
    A<B
    
    输出样例#1: 
    Sorted sequence determined after 4 relations: ABCD.
    输入样例#2: 
    3 2
    A<B
    B<A
    输出样例#2: 
    Inconsistency found after 2 relations.
    输入样例#3: 
    26 1
    A<Z
    输出样例#3: 
    Sorted sequence cannot be determined

     

    这道题我来提供一种tarjan+拓扑排序的做法,首先我们考虑满足第二种情况的序列,如果存在矛盾,那么这个图中一定存在环,这样我们就可以用tarjan缩点判断一下是否存在环,有一点需要注意,就是如果小于号两边的数相同,那么就一定产生矛盾(非常坑)。对于第一种情况的序列,不难看出这个序列的拓扑序一定是唯一的,而且一定不存在环,也就是说每次拓扑时在栈中的元素一定只有唯一的一个,这样只需在每次拓扑开始时判断一下元素个数即可。如果第一和第二种情况均不满足,那么一定就是第三种情况咯。

    最后附上代码:

      1 #include<iostream>
      2 #include<string>
      3 #include<cmath>
      4 #include<cstring>
      5 #include<cstdio>
      6 #include<stack>
      7 #define maxn 1005
      8 using namespace std;
      9 
     10 struct edge
     11 {
     12     int next;
     13     int to;
     14 }g[maxn<<1];
     15 int n,m,num,col,tot,cnt,pd,cnt2,cc,pd1;
     16 int last[maxn],de[maxn],dfn[maxn],low[maxn],co[maxn],de1[maxn];
     17 char aa[5],bb[maxn];
     18 stack<int>s;
     19 stack<int>ss;
     20 
     21 void add(int from,int to)
     22 {
     23     g[++num].next=last[from];
     24     g[num].to=to;
     25     last[from]=num;
     26 }
     27 
     28 void topo()
     29 {
     30     for(int i=1;i<=n;i++)
     31     {
     32         if(de1[i]==0)
     33         {
     34             ss.push(i);
     35         }
     36     }
     37     while(ss.size())
     38     {
     39         if(ss.size()>1)//如果栈中多余一个元素,说明topo序不唯一 
     40         {
     41             pd1=1;
     42             break;
     43         }
     44         int u=ss.top();ss.pop();
     45         bb[++cc]=char(u+'A'-1);
     46         for(int i=last[u];i;i=g[i].next)
     47         {
     48             int v=g[i].to;
     49             de1[v]--;
     50             if(de1[v]==0)
     51             {
     52                 ss.push(v);
     53             }
     54         }
     55     }
     56 }
     57 
     58 void tarjan(int u)
     59 {
     60     dfn[u]=low[u]=++tot;
     61     s.push(u);
     62     for(int i=last[u];i;i=g[i].next)
     63     {
     64         int v=g[i].to;
     65         if(!dfn[v])
     66         {
     67             tarjan(v);
     68             low[u]=min(low[u],low[v]);
     69         }
     70         else if(!co[v])
     71         {
     72             low[u]=min(low[u],dfn[v]);
     73         }
     74     }
     75     if(low[u]==dfn[u])
     76     {
     77         col++;cnt=0;
     78         for(;;)
     79         {
     80             int x=s.top();s.pop();
     81             co[x]=col;
     82             cnt++;
     83             if(cnt>1) pd=1;//如果一个强联通分量中存在不止一个点,说明有环 
     84             if(x==u) break;
     85         }
     86     }
     87 }
     88 
     89 int main()
     90 {
     91     scanf("%d%d",&n,&m);
     92     for(int i=1;i<=m;i++)
     93     {
     94         scanf("%s",aa);
     95         add(aa[0]-'A'+1,aa[2]-'A'+1);
     96         if(aa[0]-'A'+1==aa[2]-'A'+1) 
     97         {
     98             printf("Inconsistency found after %d relations.",i);//这里需要特判一下,不然第一个点会wa 
     99             return 0;    
    100         }    
    101         de[aa[2]-'A'+1]++;
    102         de1[aa[2]-'A'+1]=de[aa[2]-'A'+1];
    103         for(int j=1;j<=n;j++)
    104         de1[j]=de[j];
    105         tot=0;col=0;cc=0;pd1=0;
    106         memset(co,0,sizeof(co));
    107         memset(dfn,0,sizeof(dfn));
    108         memset(low,0,sizeof(low));
    109         while(s.size()) s.pop();
    110         while(ss.size()) ss.pop();
    111         for(int j=1;j<=n;j++)
    112         {
    113             if(!dfn[j])
    114             {
    115                 tarjan(j);//tarjan判环 
    116             }
    117         }
    118         if(pd==1) 
    119         {
    120             printf("Inconsistency found after %d relations.",i);
    121             return 0;
    122         }
    123         topo();//topo检查topo序是否唯一 
    124         if(pd1==0)
    125         {
    126             printf("Sorted sequence determined after %d relations: ",i);
    127             for(int j=1;j<=n;j++)
    128             {
    129                 printf("%c",bb[j]);
    130             }
    131             printf(".");
    132             return 0;
    133         }
    134     }
    135     printf("Sorted sequence cannot be determined.");
    136     return 0; 
    137 }
    View Code
  • 相关阅读:
    我们在期待什么?
    ASP.NET的本质–IIS以及进程模式
    javascript开发中要注意的事情
    通过配置web.config发电子邮件详解
    VS2005 中文版下载
    td自动换行CSS
    巧妙利用图片IMG的onerror事件
    网页 页面不缓存
    JS检测对像(支持多版本)
    利用js预缓存图片
  • 原文地址:https://www.cnblogs.com/snowy2002/p/10547989.html
Copyright © 2011-2022 走看看