您的位置:首页 > 其它

poj 1094 简单拓扑排序

2016-07-08 19:01 288 查看
题意:

给定一组字母的大小关系判断他们是否能组成唯一的拓扑序列。是典型的拓扑排序,但输出格式上确有三种形式:

   1.该字母序列有序,并依次输出;

   2.该序列不能判断是否有序;

   3.该序列字母次序之间有矛盾,即有环存在。

分析:
每次加入一条边,进行一次拓扑排序,判断是否可以唯一确定序列(唯一的话就是每次选点只有一个选择),是否矛盾(即有环,判断入队的数量即可,无环的话每个点都会入队一次)。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stack>
#include<map>
#include<vector>
#include<queue>
using namespace std;
const int N=27;
int in
,inq
; //入度
int g

; //判断是否有边
int ans
; //保存排序结果
int n,m;
int toposort()
{
memcpy(inq,in,sizeof(in));
queue<int>q;
for(int i=0;i<n;i++)if(!inq[i])q.push(i);
bool flag=0;
int cnt=0;
while(!q.empty()){
if(q.size()>1)flag=1; //如果队列中有多个可选点,那么排序就不能唯一确定
int t=q.front();q.pop();
ans[cnt++]=t;
for(int i=0;i<n;i++){
if(g[t][i]){
inq[i]--;
if(!inq[i])q.push(i);
}
}
}
if(cnt!=n)return 0; //有环
if(!flag)return 1; //序列唯一
return 2; //拓扑排序
}

int main()
{
char s[10];
while(~scanf("%d%d",&n,&m)&&(n+m)){
memset(in,0,sizeof(in));
memset(g,0,sizeof(g));
int i;
for(i=1;i<=m;i++){
scanf("%s",s);
in[s[2]-'A']++;
g[s[0]-'A'][s[2]-'A']=1;
int t=toposort();
if(t==0){
printf("Inconsistency found after %d relations.\n",i);
break;
}
else if(t==1){
printf("Sorted sequence determined after %d relations: ",i);
for(int j=0;j<n;j++)printf("%c",(char)('A'+ans[j]));
printf(".\n");break;
}
}
if(i>m)printf("Sorted sequence cannot be determined.\n");
else for(i=i+1;i<=m;i++)scanf("%s",s);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: