poj1094 拓扑排序(出度入度简单使用)

Sorting It All Out
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 37764   Accepted: 13327

Description

An ascending sorted sequence of distinct values is one in which some form of a less-than operator is used to order the elements from smallest to largest. For example, the sorted sequence A, B, C, D implies that A < B, B < C and C < D. in this problem, we will give you a set of relations of the form A < B and ask you to determine whether a sorted order has been specified or not.

Input

Input consists of multiple problem instances. Each instance starts with a line containing two positive integers n and m. the first value indicated the number of objects to sort, where 2 <= n <= 26. The objects to be sorted will be the first n characters of the uppercase alphabet. The second value m indicates the number of relations of the form A < B which will be given in this problem instance. Next will be m lines, each containing one such relation consisting of three characters: an uppercase letter, the character "<" and a second uppercase letter. No letter will be outside the range of the first n letters of the alphabet. Values of n = m = 0 indicate end of input.

Output

For each problem instance, output consists of one line. This line should be one of the following three: 

Sorted sequence determined after xxx relations: yyy...y. 
Sorted sequence cannot be determined. 
Inconsistency found after xxx relations. 

where xxx is the number of relations processed at the time either a sorted sequence is determined or an inconsistency is found, whichever comes first, and yyy...y is the sorted, ascending sequence. 

Sample Input

4 6
A<B
A<C
B<C
C<D
B<D
A<B
3 2
A<B
B<A
26 1
A<Z
0 0

Sample Output

Sorted sequence determined after 4 relations: ABCD.
Inconsistency found after 2 relations.
Sorted sequence cannot be determined.

题目链接:点击打开链接

题目大意:给你一堆A<B这样的顺序,进行拓扑,判断到第几次满足条件了就输出,不需要管后面的东西。要么顺序确定,要么顺序冲突,要么结尾了还不确定。

题目思路:首先理解两个概念,入度和出度,入度就是插入这个点的边的数量(指向这个点),出度就是这个点出去的边的数量。对于一个确定了顺序的序列,每一个节点的出度入度之和肯定为n-1,(自己想一下),那这道题就每次输入边的时候对出度入度进行操作就可以了,具体看代码,比较详细。

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<math.h>
#include<cmath>
#include<time.h>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<algorithm>
#include<numeric>
using namespace std;
typedef  long long ll;
const int maxn=30;
int g[maxn][maxn];
char s[10];
struct peo{
	int in,ou;//  存放每一个节点的出度和入度 
	char id;
}aa[40];
bool cmp(peo a,peo b){
	return a.ou>b.ou;
}
int main(){
	int n,m;
	while(scanf("%d%d",&n,&m),n&&m){
		memset(g,0,sizeof(g));
		for(int i=1;i<=n;i++){
			aa[i].in=0;
			aa[i].ou=0;
			aa[i].id='A'+i-1;
		}
		int to,flag=1;//flag为1 表示还没有输出过 
		for(to=1;to<=m;to++){
			scanf("%s",s);
			if(!flag)continue;
			int a=s[0]-'A'+1,b=s[2]-'A'+1;//将字符转化为数字  更简单 
			if(g[b][a]||a==b){//如果存在环 或者输入的是A<A 
				printf("Inconsistency found after %d relations.\n",to);
				flag=0;
			}
			if(g[a][b])continue;//如果关系已经存在  就不用再操作 
			g[a][b]=1;//建立关系 
			aa[a].ou++;//节点出度入度操作 
			aa[b].in++;
			for(int i=1;i<=n;i++){
				if(g[i][a]){//  存在i-a  肯定存在 a-b   i出度++   b入度++ 
					if(g[i][b])continue;//如果已经存在关系  说明之前操作过了  continue 
					g[i][b]=1;
					aa[i].ou++;
					aa[b].in++;
				}
				if(g[b][i]){//  与上同理 
					if(g[a][i])continue;
					g[a][i]=1;
					aa[i].in++;
					aa[a].ou++;
				}
			}
			int f=1;
			for(int i=1;i<=n;i++){
				if(aa[i].in+aa[i].ou!=n-1){//每一个节点 出度入度之和为n-1  即整个序列关系确定 
					f=0;
					break;
				}
			}
			if(f){
				flag=0;
				sort(aa+1,aa+1+n,cmp);//按照出度进行排序  
				printf("Sorted sequence determined after %d relations: ",to);
				for(int i=1;i<=n;i++){
					printf("%c",aa[i].id);
				}
				printf(".\n");
			}
		}
		if(flag)printf("Sorted sequence cannot be determined.\n");//如果flag还是1   说明之前没有输出  顺序不确定 
	}
}

猜你喜欢

转载自blog.csdn.net/ysk850874665/article/details/80185314