P1347 排序

链接:https://www.luogu.com.cn/problem/P1347
题目:

由于数据量很小,所以可以在线处理数据。
首先判断有没有环(这里不一定可以根据拓扑排序写出来,因为有的环可以只有部分节点,所以必须遍历所有节点的路径,判断有没有环);
然后查看入度为0的点,如果没有环而且入度为0的点多于1个,那么就是无法确定,如果没有点那么显然就是一个环,上一步可以判断出来。
如果只有一个,那么判断能不能排序,就是拓扑排序能不能走到底。
代码:

#include<iostream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<sstream>
#include<string>
#include<string.h>
#include<iomanip>
#include<stdlib.h>
#include<map>
#include<queue>
#include<limits.h>
#include<climits>
#include<fstream>
#include<stack>
typedef long long ll;
using namespace std;
const int N = 30; int n;
int rd[N]; vector<int>G[N];
int rd_tem[N];bool vis[N];bool jd = true;
void dfsk(int id);
bool hasroll(int n)
{
	
	memset(vis, 0, sizeof(vis));
	for (int i = 1; i <= n; i++)
	{
		dfsk(i);//dfsk,true::有环
	}
	return jd;
}

void dfsk(int id)
{
	vis[id] = true;
	if (jd)return;
	for (int u : G[id])
	{
		if (vis[u])
		{
			jd = true; return;
		}
		if (jd)return;
		dfsk(u);
	}
	if (jd)return;
	vis[id] = false;
}
int dfs(int id, queue<int>*q)
{
	if (q->size() == n)return 0;
	int knum = 0; int kid = 0;
	for (int i = 0; i < G[id].size(); i++)
	{
		int v = G[id][i];
		rd_tem[v]--;
		if (!rd_tem[v]) { knum++; kid = v; }
	}
	if (knum > 1)return 3;
	if (knum == 0)return 1;
	q->push(kid);
	return dfs(kid, q);
	
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	int m;
	cin >> n >> m;
	for(int i=1;i<=m;i++)
	{
		string s; cin >> s;
		if(s[0] == s[2])
		{
			cout << "Inconsistency found after " << i << " relations.";
			return 0;
		}
		G[s[0] - 'A'+1].push_back(s[2] - 'A'+1);
		rd[s[2] - 'A'+1]++;
		int numofzero = 0; int zeroid = 0;
		for (int i = 1; i <= n; i++)
			if (!rd[i])
			{
				numofzero++;
				zeroid = i;
			}
		if (!numofzero)
		{
			cout << "Inconsistency found after " << i << " relations.";
			return 0;
		}
		jd = false;
		if(hasroll(n))
		{
			cout << "Inconsistency found after " << i << " relations.";
			return 0;
		}
		if (numofzero > 1 )
			continue;
			
		//环 or 线
		for (int i = 1; i <= n; i++)rd_tem[i] = rd[i];
		queue<int>ans;
		ans.push(zeroid);
		int jd = dfs(zeroid,&ans);
		
		if (jd == 1)//环,直接跳
		{
			cout << "Inconsistency found after " << i << " relations.";
			return 0;
		}
		else if (jd == 0)//线,肯定行
		{
			cout << "Sorted sequence determined after " << i << " relations: ";
			while (!ans.empty()) { char s='A' + (ans.front() - 1); cout << s; ans.pop(); }
			cout << '.';
			return 0;
		}
	}
	cout << "Sorted sequence cannot be determined.";
	return 0;
}

posted on 2024-05-14 10:18  WHUStar  阅读(10)  评论(0编辑  收藏  举报