POJ1094 Sorting It All Out
Posted xiaowuga
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ1094 Sorting It All Out相关的知识,希望对你有一定的参考价值。
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的主要内容,如果未能解决你的问题,请参考以下文章
POJ 1094 Sorting It All Out(拓扑排序判环)
POJ 1094: Sorting It All Out( 拓扑排序 )