Sorting It All Out--POJ 1094

1、题目类型:图论、拓扑排序。

2、解题思路:(1)每输入一组数据,进行拓扑排序;(2)内部形成环时(即出现冲突)TuoPu()返回-1;内部存在多个入度为0的点时(即无法判断)此时将f标识为1;当拓扑排序正确时,TuoPu()返回排序成功的节点个数;(3)根据TuoPu()的返回值,输出结果,仅当其返回值等于输入N时,结果正确。

3、注意事项:当存在冲突或者拓扑排序成功时,之后的输入不对结果造成影响。

4、实现方法:

#include<iostream>
#include
<queue>
#include
<string>
using namespace std;

int n,m,cnt,f,arr[26],map[26][26];
bool flag[26],vis[26];
string str;

//返回排序成功时内部的元素个数
int TuoPu()
{
int i,j,count=0;
queue
<int> Q;
memset(arr,
0,sizeof(arr));
memset(flag,
0,sizeof(flag));
memset(vis,
0,sizeof(vis));
str
="";
cnt
=0,f=0;
for(i=0;i<26;i++)
for(j=0;j<26;j++)
if(map[i][j])
{
vis[i]
=1;vis[j]=1;
arr[j]
++;
}
//记录节点的总数
for(i=0;i<26;i++)
if(vis[i])
count
++;
//入度为0的入栈
for(i=0;i<26;i++)
if(!arr[i]&&vis[i])
{
flag[i]
=1;
Q.push(i);
}
//存在环
if(Q.size()==0)
return -1;
//存在多个入度为0的情况,无法判断
else if(Q.size()>1)
f
=1;
//队列内部拓扑判断
while(!Q.empty())
{
int tmp=Q.front();
cnt
++;
Q.pop();
str
+=tmp+'A';
for(i=0;i<26;i++)
{
if(!flag[i]&&map[tmp][i]&&vis[i])
arr[i]
--;
}
int t=0;
for(i=0;i<26;i++)
{
if(!flag[i]&&!arr[i]&&vis[i])
{
flag[i]
=1;
Q.push(i);
t
++;
}
}
if(Q.size()==0&&cnt!=count)
return -1;
if(t>1)
f
=1;
}
return cnt;
}

int main()
{
char ch1,op,ch2;
int i,mark,pos,tmp;
while(cin>>n>>m)
{
if(n==0&&m==0)
break;
memset(map,
0,sizeof(map));
mark
=0;
for(i=0;i<m;i++)
{
cin
>>ch1>>op>>ch2;
map[ch1
-'A'][ch2-'A']=1;
//没有找到且没有出错
if(mark==0)
{
tmp
=TuoPu();
if(tmp==-1)
{
pos
=i+1;
mark
=1;
}
else if(tmp==-2)
continue;
else if(tmp==n&&f==0)
{
pos
=i+1;
mark
=2;
}
}
}
if(mark==2&&f==0)
cout
<<"Sorted sequence determined after "<<pos<<" relations: "<<str<<"."<<endl;
else if(mark==1)
cout
<<"Inconsistency found after "<<pos<<" relations."<<endl;
else
cout
<<"Sorted sequence cannot be determined."<<endl;
}
return 0;
}
posted @ 2010-08-09 21:33  勇泽  阅读(1521)  评论(5编辑  收藏  举报