luogu1980 车站分级

题目大意

  一些火车站排成一行。给出一些火车的停靠站情况,要求对每一个火车,其经过且不停靠的站的级别比它任意停靠的站的级别小。问所有车站最少需要多少个级别。

题解

  不要只看到这道题的背景设立在一个区间上,就只想线段上的动规与贪心。由火车停靠站的情况可以得到不同站与不同站之间的级别满足偏序关系,这样就可以建立拓扑图求最长路径即可。

  普通建图$O(nm)$,要注意重边的情况,否则会MLE。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <stack>
#include <cassert>
using namespace std;

const int MAX_NODE = 1010;

struct TopGraph
{
private:
    struct Node
    {
        vector<Node*> Next;
        int Dist, DfsN;
    }_nodes[MAX_NODE];
    stack<Node*> St;
    int TotNode;

    void Dfs(Node *cur)
    {
        if (cur->DfsN == 2)
            return;
        assert(cur->DfsN != 1);
        cur->DfsN = 1;
        for (int i = 0; i < cur->Next.size(); i++)
            Dfs(cur->Next[i]);
        cur->DfsN = 2;
        St.push(cur);
    }

public:
    void Init(int n)
    {
        TotNode = n;
    }

    void AddEdge(int u, int v)
    {
        _nodes[u].Next.push_back(_nodes + v);
    }

    int LongestPath()
    {
        for (int i = 1; i <= TotNode; i++)
            Dfs(_nodes + i);
        int ans = 0;
        while (!St.empty())
        {
            Node *cur = St.top();
            St.pop();
            ans = max(ans, cur->Dist);
            for (int i = 0; i < cur->Next.size(); i++)
                cur->Next[i]->Dist = max(cur->Next[i]->Dist, cur->Dist + 1);
        }
        return ans;
    }
}g;

int stopPos[MAX_NODE];
bool Vis[MAX_NODE][MAX_NODE];

int main()
{
    int len, trainCnt;
    scanf("%d%d", &len, &trainCnt);
    g.Init(len);
    for (int i = 1; i <= trainCnt; i++)
    {
        int stopCnt;
        scanf("%d", &stopCnt);
        for (int j = 1; j <= stopCnt; j++)
            scanf("%d", stopPos + j);
        for (int j = 1; j < stopCnt; j++)
            for (int k = stopPos[j] + 1; k <= stopPos[j + 1] - 1; k++)
                for (int l = 1; l <= stopCnt; l++)
                {
                    if (!Vis[k][stopPos[l]])
                    {
                        g.AddEdge(k, stopPos[l]);
                        Vis[k][stopPos[l]] = true;
                    }
                }
    }
    printf("%d\n", g.LongestPath() + 1);
    return 0;
}

  $O(n)$算法,对每个火车建立一个虚点,所有经过不停靠的站向虚点连边权1的边,虚点向所有停靠站连边权0的边,与原方法等价,却减少了时间复杂度。 

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <stack>
#include <cassert>
using namespace std;

const int MAX_NODE = 2010;

struct TopGraph
{
private:
	struct Edge;

	struct Node
	{
		Edge *Head;
		int Dist, DfsN;
	}_nodes[MAX_NODE];
	stack<Node*> St;
	int TotNode;

	struct Edge
	{
		Node *To;
		Edge *Next;
		int Weight;
	}_edges[MAX_NODE * MAX_NODE];
	int _eCount;

	void Dfs(Node *cur)
	{
		if (cur->DfsN == 2)
			return;
		assert(cur->DfsN != 1);
		cur->DfsN = 1;
		for (Edge *e = cur->Head; e; e = e->Next)
			Dfs(e->To);
		cur->DfsN = 2;
		St.push(cur);
	}

public:
	void Init(int n)
	{
		TotNode = n;
	}

	void AddEdge(int uId, int vId, int w)
	{
		Node *from = _nodes + uId, *to = _nodes + vId;
		Edge *e = _edges + ++_eCount;
		e->To = to;
		e->Weight = w;
		e->Next = from->Head;
		from->Head = e;
	}

	int LongestPath()
	{
		for (int i = 1; i <= TotNode; i++)
			Dfs(_nodes + i);
		int ans = 0;
		while (!St.empty())
		{
			Node *cur = St.top();
			St.pop();
			ans = max(ans, cur->Dist);
			for (Edge *e = cur->Head; e; e = e->Next)
				e->To->Dist = max(e->To->Dist, cur->Dist + e->Weight);
		}
		return ans;
	}
}g;

int stopPos[MAX_NODE];

int main()
{
	int len, trainCnt;
	scanf("%d%d", &len, &trainCnt);
	g.Init(len + trainCnt);
	for (int i = 1; i <= trainCnt; i++)
	{
		int stopCnt;
		scanf("%d", &stopCnt);
		for (int j = 1; j <= stopCnt; j++)
			scanf("%d", stopPos + j);
		for (int j = 1; j < stopCnt; j++)
			for (int k = stopPos[j] + 1; k <= stopPos[j + 1] - 1; k++)
				g.AddEdge(k, len + i, 1);
		for (int j = 1; j <= stopCnt; j++)
			g.AddEdge(len + i, stopPos[j], 0);
	}
	printf("%d\n", g.LongestPath() + 1);
	return 0;
}

  

转载于:https://www.cnblogs.com/headboy2002/p/9492242.html

数据治理是确保数据准确性、可靠性、安全性、可用性和完整性的体系和框架。它定义了组织内部如何使用、存储、保护和共享数据的规则和流程。数据治理的重要性随着数字化转型的加速而日益凸显,它能够提高决策效率、增强业务竞争力、降低风险,并促进业务创新。有效的数据治理体系可以确保数据在采集、存储、处理、共享和保护等环节的合规性和有效性。 数据质量管理是数据治理中的关键环节,它涉及数据质量评估、数据清洗、标准化和监控。高质量的数据能够提升业务决策的准确性,优化业务流程,并挖掘潜在的商业价值。随着大数据和人工智能技术的发展,数据质量管理在确保数据准确性和可靠性方面的作用愈发重要。企业需要建立完善的数据质量管理和校验机制,并通过数据清洗和标准化提高数据质量。 数据安全与隐私保护是数据治理中的另一个重要领域。随着数据量的快速增长和互联网技术的迅速发展,数据安全与隐私保护面临前所未有的挑战。企业需要加强数据安全与隐私保护的法律法规和技术手段,采用数据加密、脱敏和备份恢复等技术手段,以及加强培训和教育,提高安全意识和技能水平。 数据流程管理与监控是确保数据质量、提高数据利用率、保护数据安全的重要环节。有效的数据流程管理可以确保数据流程的合规性和高效性,而实时监控则有助于及时发现并解决潜在问题。企业需要设计合理的数据流程架构,制定详细的数据管理流程规范,并运用数据审计和可视化技术手段进行监控。 数据资产管理是将数据视为组织的重要资产,通过有效的管理和利用,为组织带来经济价值。数据资产管理涵盖数据的整个生命周期,包括数据的创建、存储、处理、共享、使用和保护。它面临的挑战包括数据量的快速增长、数据类型的多样化和数据更新的迅速性。组织需要建立完善的数据管理体系,提高数据处理和分析能力,以应对这些挑战。同时,数据资产的分类与评估、共享与使用规范也是数据资产管理的重要组成部分,需要制定合理的标准和规范,确保数据共享的安全性和隐私保护,以及建立合理的利益分配和权益保障机制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值