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