#include <cstdio> #include <cstring> #include <stack> #include <iostream> using namespace std; #define N 1005 int first[N] , in[N] , rec[N] , vis[N] , k; char str[N][5]; struct Node { int y , next; }node[N<<1]; void add_edge(int x,int y) { in[y]++; node[k].y = y , node[k].next = first[x]; first[x] = k++; } int dag(int cnt , int n) { int copy_in[N]; for(int i = 0 ; i<n ; i++) copy_in[i] = in[i]; int t = 0; stack<int> s; for(int i = 0 ; i<n ; i++){ if(!copy_in[i] && vis[i]) { // cout<<"there: "<<i<<" "<<cnt<<" "<<n<<endl; t++; s.push(i); } } int flag = 1; for(int i = 0 ; i<cnt ; i++){ if(s.empty()){ return -1; } if(s.size() > 1) flag = 0; int u = s.top(); s.pop(); rec[i] = u; for(int i=first[u] ; i!=-1 ; i=node[i].next){ int v = node[i].y; copy_in[v]--; if(!copy_in[v]) s.push(v); } } if(cnt == n && t == 1 && flag) return 1; else return 0; } int main() { // freopen("a.in" , "rb" , stdin); int n,m,a,b; while(~scanf("%d%d",&n,&m)){ if(n==0 && m==0) break; memset(first , -1 , sizeof(first)); memset(in , 0 , sizeof(in)); memset(vis , 0 , sizeof(vis)); for(int i = 0 ; i<m ; i++){ scanf("%s",str[i]); } int cnt = 0;//计算当前传入的所有边中含有的点数 k=0; for(int i=0 ; i<m ; i++){ //add edge a = str[i][0] - ‘A‘; if(!vis[a]){ cnt++; vis[a]=1; } b = str[i][2] - ‘A‘; if(!vis[b]){ cnt++; vis[b]=1; } // cout<<"here: "<<a<< " "<<b<<endl; add_edge(a,b); int falg = dag(cnt , n); if(falg == -1) { printf("Inconsistency found after %d relations.\n" , i+1); break; } else if(falg == 1) { printf("Sorted sequence determined after %d relations: " , i+1); for(int i=0;i<n;i++) { char c = ‘A‘+rec[i]; cout<<c; } printf(".\n"); break; } else{ if(i<m-1) continue; printf("Sorted sequence cannot be determined.\n"); } } } return 0; }
这道题就是逐步判断是否找到合适的顺序,找到了就停止将顺序输出
这里最大的问题是,在有向图中我们进行DAG查询的过程中,每一步都得保证只有一个点没有入度,否则多点没有入度,分不清先后顺序
原文:http://www.cnblogs.com/CSU3901130321/p/4100851.html