zoukankan      html  css  js  c++  java
  • 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;
    }
    

      

  • 相关阅读:
    微信红包限额提升方法
    微信从业人员推荐阅读的100本经典图书
    微信裂变红包
    微信公众平台开发最佳实践(第2版)
    微信公众平台开发(108) 微信摇一摇
    微信支付样例
    微信行业解决方案
    牛逼顿
    微信支付开发(4) 扫码支付模式二
    微信公众平台开发(107) 分享到朋友圈和发送给好友
  • 原文地址:https://www.cnblogs.com/headboy2002/p/9180447.html
Copyright © 2011-2022 走看看