• luogu1347 排序


    题目大意

       一个不同的值的升序排序数列指的是一个从左到右元素依次增大的序列。给你一系列形如A<B的关系,并要求你判断是否能够根据这些关系确定这个数列的顺序(能,矛盾,不确定)。确定n个元素的顺序后即可结束程序,可以不用考虑确定顺序之后出现矛盾的情况。

     题解

      如果A<B,则在图中A结点向B结点连一条有向边,这样,如果出现了矛盾情况,则有向图中出现了环。如果确定了数列的顺序,则图中存在一条链把1~n所有结点都串起来了。换句话说,把这个有向图的边权都设为1,则该有向图中的最长路径为n时,能够确定序列顺序。那么这道题就是拓扑排序的模板题了。

    #include <cstdio>
    #include <cstdarg>
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    #include <stack>
    #include <string>
    #include <iostream>
    using namespace std;
    
    #define NotVis 0
    #define Finished 1
    #define InStack -1
    
    const int MAX_NODE = 50;
    
    struct TopSort
    {
    	int N;
    	bool HaveCircle;
    	int MaxDist;
    
    	struct Node
    	{
    		int Color;//0:NotVis 1:Finished -1:InStack
    		int Dist;
    		vector<Node*> Next;
    	}_nodes[MAX_NODE];
    	stack<Node*> St;
    
    	void Dfs(Node *cur)
    	{
    		if (cur->Color == InStack)
    		{
    			HaveCircle = true;
    			return;
    		}
    		if (cur->Color == Finished)
    			return;
    		cur->Color = InStack;
    		for (int i = 0; i < cur->Next.size(); i++)
    		{
    			if (HaveCircle)
    				return;
    			Dfs(cur->Next[i]);
    		}
    		cur->Color = Finished;
    		St.push(cur);
    	}
    
    	TopSort(int n):N(n){}
    
    	void Build(int from, int to)
    	{
    		_nodes[from].Next.push_back(_nodes + to);
    	}
    
    	void Init()
    	{
    		MaxDist = -1;
    		while (!St.empty())
    			St.pop();
    		HaveCircle = false;
    		for (int i = 1; i <= N; i++)
    			_nodes[i].Color = _nodes[i].Dist = 0;
    	}
    
    	void GetMaxDist()
    	{
    		if (HaveCircle)
    		{
    			MaxDist = -1;
    			return;
    		}
    		stack<Node*> tempSt = St;
    		while (!tempSt.empty())
    		{
    			Node *cur = tempSt.top();
    			tempSt.pop();
    			MaxDist = max(MaxDist, cur->Dist);
    			for (int i = 0; i < cur->Next.size(); i++)
    				cur->Next[i]->Dist = max(cur->Next[i]->Dist, cur->Dist + 1);
    		}
    	}
    
    	void Proceed()
    	{
    		Init();
    		for (int i = 1; i <= N; i++)
    			Dfs(_nodes + i);
    		GetMaxDist();
    	}
    };
    
    int main()
    {
    	int totNode, opCnt;
    	string s;
    	cin >> totNode >> opCnt;
    	static TopSort g(totNode);
    	for (int i = 1; i <= opCnt; i++)
    	{
    		cin >> s;
    		int a = s[0] - 'A' + 1, b = s[2] - 'A' + 1;
    		if (s[1] == '>')
    			swap(a, b);
    		g.Build(a, b);
    		g.Proceed();
    		if (g.HaveCircle)
    		{
    			printf("Inconsistency found after %d relations.
    ", i);
    			return 0;
    		}
    		else if (g.MaxDist == totNode - 1)
    		{
    			printf("Sorted sequence determined after %d relations: ", i);
    			stack<TopSort::Node*> temp = g.St;
    			while (!temp.empty())
    			{
    				printf("%c", (int)(temp.top() - g._nodes) - 1 + 'A');
    				temp.pop();
    			}
    			printf(".
    ");
    			return 0;
    		}
    	}
    	printf("Sorted sequence cannot be determined.
    ");
    	return 0;
    }
    

      

  • 相关阅读:
    波特率原理【转】
    求助大神!怎样批量删除数据库表中某个字段中同样的一段字符!
    1033. To Fill or Not to Fill (25)
    http协议
    【数据结构与算法】二叉树深度遍历(递归)
    2015届求职经历
    Codeforces Round #245 (Div. 1)——Working out
    泛泰A900 刷4.4专用中文TWRP2.7.1.1版 支持自己主动识别手机版本号(全球首创)
    实现简答LinkedList
    oracle的内存管理(之中的一个)
  • 原文地址:https://www.cnblogs.com/headboy2002/p/9180447.html
Copyright © 2020-2023  润新知