【洛谷P1347】排序

题目大意:给定 N 个变量和 M 个变量之间的偏序关系,问能否求出这 N 个变量之间的一个全序。若能,输出最少利用多少条已知信息即可求的结果,且输出该全序;若无解,输出到第几条已知信息可以判定无解;若读到最后一条信息也无法判断,输出无法判断。

题解:偏序关系自然对应着一个有向图,每一个已知信息等价为给这个有向图加一条边,若能够得到全序,则证明拓扑排序过程中能够找出一条长度为 N 的链,若无解,则是在拓扑排序过程中存在自环,否则就是无法判断。

代码如下

#include <bits/stdc++.h>
using namespace std;
const int maxn=30;

vector<int> G[maxn];
char ops[10];
int n,m,idx,indeg[maxn],tmp[maxn],stk[maxn],top,d[maxn];//d[i]为以 i 结尾的最长路径
bool circle,certain;

inline void add_edge(int from,int to){G[from].push_back(to),++indeg[to];}

void topo_sort(int now){
	queue<int> q;int dep=1;//dep为当前DAG上的最长路径的长度
	for(int i=1;i<=n;i++)d[i]=0;
	for(int i=1;i<=n;i++){
		tmp[i]=indeg[i];
		if(!tmp[i])q.push(i),d[i]=1;
	}
	top=0;
	while(q.size()){
		int u=q.front();q.pop();
		stk[++top]=u;
		for(int i=0;i<G[u].size();i++){
			int v=G[u][i];--tmp[v];
			if(!tmp[v])q.push(v);
			d[v]=max(d[v],d[u]+1);
			dep=max(dep,d[v]);
		}
	}
	if(top^n)circle=1,idx=now;
	else if(dep==n)certain=1,idx=now;
}

void solve(){
	for(int i=1;i<=m;i++){
		scanf("%s",ops+1);
		if(circle||certain)break;
		int from=ops[1]-'A'+1,to=ops[3]-'A'+1;
		add_edge(from,to);
		topo_sort(i);
	}
	if(certain){
		printf("Sorted sequence determined after %d relations: ",idx);
		for(int i=1;i<=n;i++)printf("%c",stk[i]+'A'-1);
		printf(".
");
	}
	else if(circle)printf("Inconsistency found after %d relations.
",idx);
	else printf("Sorted sequence cannot be determined.
");
}

int main(){
	scanf("%d%d",&n,&m);
	solve();
	return 0;
}
原文地址:https://www.cnblogs.com/wzj-xhjbk/p/9932184.html