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
posted @ 2019-03-17 17:51  snowy2002  阅读(594)  评论(3编辑  收藏  举报