您的位置:首页 > 其它

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的原因。。。),因为只要出现有环,就不可能进行拓扑排序

代码:

#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");
}
}
}

这道题的思路不难,不过代码实现时,要考虑很多,多思考。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息