一個不一樣的值的升序排序數列指的是一個從左到右元素依次增大的序列,例如,一個有序的數列A,B,C,D 表示A<B,B<C,C<D。在這道題中,咱們將給你一系列形如A<B的關係,並要求你判斷是否可以根據這些關係肯定這個數列的順序。ios
輸入格式: ide
第一行有兩個整數n,m,n表示須要排序的元素數量,2<=n<=26,第1到n個元素將用大寫的A,B,C,D....表示。m表示將給出的形如A<B的關係的數量。spa
接下來有m行,每行有3個字符,分別爲一個大寫字母,一個<符號,一個大寫字母,表示兩個元素之間的關係。code
輸出格式:blog
若根據前x個關係便可肯定這n個元素的順序yyy..y(如ABC),輸出排序
Sorted sequence determined after xxx relations: yyy...y.get
若根據前x個關係即發現存在矛盾(如A<B,B<C,C<A),輸出string
Inconsistency found after 2 relations.io
若根據這m個關係沒法肯定這n個元素的順序,輸出ast
Sorted sequence cannot be determined.
(提示:肯定n個元素的順序後便可結束程序,能夠不用考慮肯定順序以後出現矛盾的狀況)
這道題我來提供一種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 }