F - Sorting It All Out(拓扑排序)

本文探讨了一种基于图的排序算法,该算法首先检查图中是否存在环,然后判断是否可以进行严格有序的排序。文章详细解释了如何通过判断结点的度数来实现排序,同时介绍了输入输出格式及样例,适用于需要对复杂关系进行排序和一致性检查的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 这个问题中优先级最高的是判断有环。一旦发现找不到度为0的结点,则立即return。
第二优先级是是否严格有序的判断。当每一步能且只能找到一个度为0的结点,则return。
第三优先级是无法确定。(当发现无法确定时,并不能立即return,因为还需要判断是否有环)

不同值的升序排序序列中,使用某种形式的小于运算符来将元素从最小到最大排序。例如,排序序列A,B,C,D意味着A<B,B<C和C<D。在这个问题中,我们将给出一组形式A<B的关系,并要求您确定是否指定了排序顺序。

输入

输入由多个问题实例组成。每个实例都以包含两个正整数n和M的行开始,第一个值表示要排序的对象数,其中2<=n<=26。要排序的对象将是大写字母的前n个字符。第二个值m表示形式A<B的关系数,在这个问题的情况下将给出。接下来是m行,每一行包含一个这样的关系,由三个字符组成:大写字母、字符“<”和第二个大写字母。任何字母都不会超出字母表前n个字母的范围。n=m=0表示输入结束。

输出量

对于每个问题实例,输出由一行组成。这一行应是以下三行之一:

在xxx关系后确定的排序序列:YYY.y。
无法确定排序顺序。
xxx关系后发现的不一致。

其中xxx是在确定排序序列或发现不一致时处理的关系数,以第一位为准,yy.y是排序的升序序列。

样本输入

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

样本输出

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

 

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<vector>
#include<cmath>
#include<string>
#include<map>
#include<queue>
using namespace std;
#define INF 0x3f3f3f3f
typedef long long ll;
struct node{
	ll id;
	ll d;
	ll next_s;
}side[1000];
ll cnt,head[27],in[27];
queue<ll> p;
void init(){
	memset(head,-1,sizeof(head));
	cnt=0;
}
void add(ll x,ll y,ll z){
	side[cnt].id=y;
	side[cnt].d=z;
	side[cnt].next_s=head[x];
	head[x]=cnt++;
}

ll judge(ll n){
	while(!p.empty()){
		p.pop();
	}
	ll temp[27],flag=0,m,loc;
	for(int i=1;i<=n;i++){
		temp[i]=in[i];
	}
	
	for(int i=1;i<=n;i++){
		m=0;
		for(int j=1;j<=n;j++){
			if(temp[j]==0){
				m++;
				loc=j;
			}
		}
		if(m==0){
			return 1;//有环 
		}
		if(m>1){//,说明了排序不唯一,目前无环,但是还是可能有环 
			flag=-1;
		}
		
		temp[loc]=-1;
		p.push(loc);
		for(int k=head[loc];k!=-1;k=side[k].next_s){
			temp[side[k].id]--;
		}
	}
	return flag;
}

int main(){
	ll n,m,sign;
	while(cin>>n>>m&&(n||m)){
		init();
		string s;
		sign=0;
		memset(in,0,sizeof(in));
		for(int i=1;i<=m;i++){
			cin>>s;
			if(sign==1)
			continue;
			ll x=s[0]-'A'+1;
			ll y=s[2]-'A'+1;
			add(x,y,0);
			in[y]++;
			ll ss=judge(n);
			if(ss==1){
				cout<<"Inconsistency found after "<<i<<" relations."<<endl;
				sign=1;
			}
			if(ss==0){
				cout<<"Sorted sequence determined after "<<i<<" relations: ";
				while(!p.empty()){
					char cc=(char)p.front()-1+'A';
					cout<<cc;
					p.pop();
				}
				cout<<"."<<endl;
				sign=1;
			}
		}
		if(sign==0){
			cout<<"Sorted sequence cannot be determined."<<endl;
		}
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值