题目大意

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

题解

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

  普通建图$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;
}

  

luogu1980 车站分级的更多相关文章

  1. 洛谷P1983 车站分级

    P1983 车站分级 297通过 1.1K提交 题目提供者该用户不存在 标签图论贪心NOIp普及组2013 难度普及/提高- 提交该题 讨论 题解 记录 最新讨论 求帮忙指出问题! 我这么和(diao ...

  2. 【洛谷P1983】车站分级

    车站分级 题目链接 首先,可以发现火车停靠站点的大小是没有什么规律的, 火车可以停靠在级别<=当前级别的站点,必须停靠在级别>=当前最高级别的站点 但是所有没有被停靠的站点级别一定比所有被 ...

  3. 【NOIP2013 普及组】车站分级

    [NOIP2013 普及组]车站分级 一.题目 [NOIP2013 普及组]车站分级 时间限制: 1 Sec  内存限制: 128 MB 提交: 3  解决: 0 [提交][状态][讨论版] 题目描述 ...

  4. 洛谷P1983车站分级

    洛谷\(P1983\)车站分级(拓扑排序) 目录 题目描述 题目分析 思路分析 代码实现 题目描述 题目在洛谷\(P1983\)上 ​ 题目: 一条单向的铁路线上,依次有编号为 \(1, 2, -, ...

  5. 洛谷 P1983 车站分级

    题目链接 https://www.luogu.org/problemnew/show/P1983 题目描述 一条单向的铁路线上,依次有编号为 1,2,…,n的 n个火车站.每个火车站都有一个级别,最低 ...

  6. 洛谷P1983车站分级题解

    题目 这个题非常毒瘤,只要还是体现在其思维难度上,因为要停留的车站的等级一定要大于不停留的车站的等级,因此我们可以从不停留的车站向停留的车站进行连边,然后从入度为0的点即不停留的点全都入队,然后拓扑排 ...

  7. NOIp2013 车站分级 【拓扑排序】By cellur925

    题目传送门 我们注意到,题目中说:如果这趟车次停靠了火车站 x,则始发站.终点站之间所有级别大于等于火车站x的都必须停靠.有阶级关系,满满的拓扑排序氛围.但是,如果我们按大于等于的关系连,等于的情况就 ...

  8. [NOIP2013]车站分级 解题报告

    妈蛋这道普及组水(神)题搞了我非常久. 一. 首先一个非常显然的事情就是每一个火车告诉了站与站之间的等级关系,所以拓扑求最长路. 可是发现暴力建边的话最坏能够达到500*500,所以时间复杂度有O(M ...

  9. LG1983 「NOIP2013」车站分级 拓扑排序

    问题描述 LG1983 题解 考虑建立有向边\((a,b)\),代表\(a\)比\(b\)低级. 于是枚举每一辆车次经过的车站\(x \in [l,r]\),如果不是车辆停靠的车站,则从\(x\)向每 ...

随机推荐

  1. Laravel5.1学习笔记12 系统架构4 服务容器

    Service Container 介绍 绑定的用法  绑定实例到接口 上下文绑定 标签 解析 容器事件 #介绍 The Laravel service container is a powerful ...

  2. FullCalendar日程设置

    顺序很重要!!!不然会报错,后面的文件会引用前面的一些东西. shili1:  http://blog.csdn.net/lizai22/article/details/53522523 shili ...

  3. Android开发问题-真机调试连接

    出现“no debuggable processes”可以: 1)尝试Tools->android->Enable ADB Intergration使之选中: 2)换一根数据线试试. 初次 ...

  4. JS高级——词法作用域

    作用域 1.js中没有块级作用域 2.如果有块级作用域,那么下面代码将会是undefined undefined <script> for (var i = 0; i < 10; i ...

  5. XML——读与写

    XML写入 private static void writeXml() { using (XmlTextWriter xml = new XmlTextWriter(@"C:\Users\ ...

  6. 剔除重复jar包,查找重复类

    作为程序员,没有遇到过jar包冲突,不是你幸运,就是你还年轻. jar包冲突有着无穷的魔力,一提到就会有说不完的怨愤,道不清的忧伤,这都是内伤.jar 包冲突就像深藏地底的地雷,看上去平常无奇,一切是 ...

  7. 170925_2 Python socket 创建UDP的服务器端和客户端

    [python版本]3.6 UDP服务器端: from socket import * from time import ctime host = '' port = 21567 buf_size = ...

  8. SpringMVC(四)@RequestParam

    使用@RequestParam可以将URL中的请求参数,绑定到方法的入参上,并通过@RequestParam的3个参数进行配置 Modifier and Type Optional Element D ...

  9. JAR包中读取资源文件

    我们常常在代码中读取一些资源文件(比如图片,音乐,文本等等).在单独运行的时候这些简单的处理当然不会有问题.但是,如果我们把代码打成一个jar包以后,即使将资源文件一并打包,这些东西也找不出来了.看看 ...

  10. webstorm_completion

    js 使用yarn 安装声明定义文件 @types/xxx koa ==> @types/koa koa-router ==> @types/koa-router 安装webstorm中的 ...