poj1094 Sorting It All Out 拓扑排序 有向图判环 vector 模拟
2017-08-21 11:15
281 查看
POJ 1094
题目大意:
输入n,m。n代表26个字母的前n个,m代表有m条输入。然后输入m条类似“A<B”形式的字符串,它代表第一个字符(A)小于第二个字符(B)。
然后根据这些字符关系,判断是否能找到一个唯一的序列使得满足这些字符的大小关系。(拓扑排序~)
如果可以的话,那么输出这个唯一的序列,不能的话,有两种情况,一是有环(A<B,B<C,C<A),二是不唯一。
这道题还明确的告诉你,从输入的第一个关系开始,如果在中途出现有环,或者可以输出正确序列,那么你可以直接输出答案。然后后续的输入就不用管了。。。
大体思路:
边输入边存图边判断,在判断期间,如果发现有环,那么就直接输出。如果能找到唯一满足n个字符的关系序列,那也直接输出。如果以上两种情况有一个发生,那么后续输入就不用管了。注意,当判断时,发现当前不能确定唯一的序列(这也有两种情况,一是出现的字符不足n个,二是入度数为零的不止一个),那我们也要判断是否有环(一直wrong的原因。。。),因为只要出现有环,就不可能进行拓扑排序
代码:
这道题的思路不难,不过代码实现时,要考虑很多,多思考。。。
题目大意:
输入n,m。n代表26个字母的前n个,m代表有m条输入。然后输入m条类似“A<B”形式的字符串,它代表第一个字符(A)小于第二个字符(B)。
然后根据这些字符关系,判断是否能找到一个唯一的序列使得满足这些字符的大小关系。(拓扑排序~)
如果可以的话,那么输出这个唯一的序列,不能的话,有两种情况,一是有环(A<B,B<C,C<A),二是不唯一。
这道题还明确的告诉你,从输入的第一个关系开始,如果在中途出现有环,或者可以输出正确序列,那么你可以直接输出答案。然后后续的输入就不用管了。。。
大体思路:
边输入边存图边判断,在判断期间,如果发现有环,那么就直接输出。如果能找到唯一满足n个字符的关系序列,那也直接输出。如果以上两种情况有一个发生,那么后续输入就不用管了。注意,当判断时,发现当前不能确定唯一的序列(这也有两种情况,一是出现的字符不足n个,二是入度数为零的不止一个),那我们也要判断是否有环(一直wrong的原因。。。),因为只要出现有环,就不可能进行拓扑排序
代码:
#include<stdio.h> #include<string.h> #include<iostream> using namespace std; #include<vector> #include<queue> vector<int>V[27];//用vector进行存图 queue<int>Q; int anss[27];//用来打印正确序列 int in[27];//存每个节点的入度数 int inn[27]; int ToPoSort(int n) { while(!Q.empty())Q.pop(); int num=0; for(int i=1; i<=n; i++) { inn[i]=in[i]; if(in[i]==0) { num++; Q.push(i); } } if(num==0)return 0;//n个节点的入度数都为零,那么肯定是个环。 if(num>1)//有可能有的字符没出现,有可能是(B<C,A<C)这种情况,虽然这样num>1时,暂时不能找到正确序列,但我们依然要判环 { //判环 int cou=0; while(!Q.empty()) { int top=Q.front(); cou++; Q.pop(); int len=0; while(len<V[top].size()) { int temp=V[top][len]; inn[temp]--; if(!inn[temp])Q.push(temp); len++; } } if(cou<n) return 0; return -1; } //num==1,我们要找正确序列了,但有环或者不唯一的话,也不行。 for(int i=1; i<=n; i++) { inn[i]=in[i]; } int unq=0; int cou=0; while(!Q.empty()) { if(Q.size()>1)unq=1;//不唯一 int top=Q.front(); anss[cou++]=top; Q.pop(); int len=0; while(len<V[top].size()) { int temp=V[top][len]; inn[temp]--; if(!inn[temp])Q.push(temp); len++; } } //cout<<"==="<<cou<<endl; if(cou<n)return 0;//有环 if(unq)return -1; return 1; } int main() { int n,m; while(~scanf("%d%d",&n,&m)) { for(int i=0; i<=27; i++) { V[i].clear(); } memset(in,0,sizeof(in)); if(!n&&!m)break; char a,c,b; int flag=0;//当flag为1时,代表已经出现输出了,后续就不用管了 for(int i=1; i<=m; i++) { cin>>a>>c>>b; if(flag)continue; in[b-'A'+1]++; V[a-'A'+1].push_back(b-'A'+1); int ans=ToPoSort(n);//边输入边存图边判断 if(ans==0) { printf("Inconsistency found after %d relations.\n",i); flag=1; } else if(ans==1) { printf("Sorted sequence determined after %d relations: ",i); for(int i=0; i<n; i++) { printf("%c",anss[i]-1+'A'); } printf(".\n"); flag=1; } } if(!flag) { printf("Sorted sequence cannot be determined.\n"); } } }
这道题的思路不难,不过代码实现时,要考虑很多,多思考。。。
相关文章推荐
- POJ 1094 Sorting It All Out 拓扑排序
- POJ 1094 Sorting It All Out 拓扑排序
- POJ1094-Sorting It All Out 拓扑排序
- poj 1094 Sorting It All Out 拓扑排序
- POJ - 1094 Sorting It All Out 拓扑排序
- POJ 1094 Sorting It All Out 拓扑排序(比较好的模板)
- POJ - 1094 Sorting It All Out 拓扑排序
- Sorting It All Out--POJ 1094
- POJ 1094 Sorting It All Out (拓扑排序)
- 拓扑排序 附POJ 1094 Sorting It All Out 解题报告
- poj 1094 Sorting It All Out
- poj 1094 Sorting It All Out (拓扑排序)
- 初学拓扑排序---POJ1094(Sorting It All Out)
- poj-1094 Sorting It All Out
- [POJ1094 Sorting It All Out]
- 【POJ】1094 Sorting It All Out(拓扑排序)
- poj 1094 Sorting It All Out(nyoj 349)
- POJ 1094 Sorting It All Out(拓扑排序)
- POJ - 1094 Sorting It All Out
- POJ-1094-Sorting It All Out