POJ1094 Sorting It All Out
阿新 • • 發佈:2017-07-24
front break con min ack lag cstring 出錯 循環
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,說明出現了環
判斷是否出現無法比較的兩個點:拓撲排序中的隊列如果同時存在兩個元素,說明這兩個元素是無法比較的
POJ1094 Sorting It All Out