天天看点

ZOJ 1060 Sorting It All Out 拓扑排序

一个简单的求拓扑排序的算法:首先要找到任意入度为0的一个顶点,删除它及所有相邻的边,再找入度为0的顶点,以此类推,直到删除所有顶点。顶点的删除顺序即为拓扑排序。但这一题有点不同,不能有并列结构的拓扑。所以每次都要判断入度为0的个数,如果个数为0则是环。如果个数大于1,则先记录这是有并列的拓扑,因为可能存在有并列也有环的情况。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string.h>
using namespace std;

const int N=27;
int mp[N][N],u[N*N],v[N*N];
int n,m,in[N];
char str[N];

int TopoSort(){
	int d[N],cnt=0,flag=0;
	memcpy(d,in,sizeof in);//d是入度
	for(int i=0;i<n;i++){
		int next=n,num=0;//统计入度为0个数
		for(int j=0;j<n;j++)
			if(d[j]==0)
				next=j,num++;
		if(num==0) return -1;//成环
		if(num>1) flag=1;//并列--不能直接返回

		d[next]=-1;//next进入排序队列,删除相关入度
		str[cnt++]=next+'A';
		for(int j=0;j<n;j++)
			if(mp[next][j]==1)
				d[j]--;
	}
	str[cnt]=0;
	if(flag) return 0;//排序不完全
	return 1;//完全排序
}

int main(){
	while(cin>>n>>m){
		if(n==0&&m==0) break;
		memset(mp,0,sizeof mp);
		memset(in,0,sizeof in);
		for(int i=0;i<m;i++){//存储边
			scanf("%s",str);
			u[i]=str[0]-'A';
			v[i]=str[2]-'A';
		}
		int ok=0;
		for(int i=0;i<m;i++){
			mp[u[i]][v[i]]=1;
			in[v[i]]++;
			int mark=TopoSort();
			if(mark==-1){
				printf("Inconsistency found after %d relations.\n",i+1);
				ok=1;break;
			}
			else if(mark==1){
				printf("Sorted sequence determined after %d relations: %s.\n",i+1,str);
				ok=1;break;
		    }
		}
		if(ok==0) printf("Sorted sequence cannot be determined.\n");
	}
	return 0;
}
           

继续阅读