妈蛋这道普及组水(神)题搞了我非常久。

一、

首先一个非常显然的事情就是每一个火车告诉了站与站之间的等级关系,所以拓扑求最长路。

可是发现暴力建边的话最坏能够达到500*500,所以时间复杂度有O(MN2)≈2.5∗108,常数相当小。

。数据水成狗,所以绝对能够过的。

二、

所以我就想到了bitset,把每辆火车做成一个长N的布尔向量。经过为1,不经过为0,第一个车站的左边和最后一个车站的右边补1,。

然后对于每一个车站,把全部它所在的位为1的向量都&起来,然后扫一遍向量连边。

这样做的时间复杂度能够用long long模拟bitset的时间复杂度来预计。就是O(MN264)≈107,常数更小了。实际跑起来事实上跟10^6差点儿相同。

三、

然后我看了一个大神的代码,发现原来是有正儿八经的O(NM)的做法的。

我们发现车站之间是比較麻烦的,所以考虑对偶转换!!

我们这样来考虑。比方说我们设火车经过的最低等级的车站为火车的等级,那么火车的等级数=车站的等级数?

依照上面的定义,火车的等级数自然是小于等于车站的等级数的。而假设一个车站不是不论什么一辆火车的等级,那么就意味着它能够下降或上升它自己的等级直到它是不论什么一辆火车的等级呢?

可是这种前提是每一辆车站都至少有一辆火车经过。所以自然我们仅仅要加一辆经过全部车站的火车就能够了。

这种话。我们仅仅须要求出火车的等级就可以了!

可是火车的等级怎么求呢?假设不存在一个车站使得两辆火车都经过它,那么显然这两辆火车之间是没有直接的等级关系的;而假设它们有交的话,那么显然在交集部分经过很多其它车站的火车的等级应该是更低的。由于低等级的车站会经过全部高等级的车站经过的车站!

一定要注意的地方:

①拓扑求最长路的时候是要求Max!!

②一定要对拍!

code(bitset):

#include<iostream>
using namespace std;
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
inline void in(int &x){
char c=getchar();
x=0;
while(c<'0'||c>'9')c=getchar();
for(;c>='0'&&c<='9';c=getchar())x=x*10+(c^'0');
}
int l[1005],r[1005];
#include<bitset>
bitset<1005> be[1005],btmp;
int next[1000005],ptr[1005],succ[1000005];
int stack[1005],level[1005],ru[1005];
int main(){
freopen("level2013.in","r",stdin);
freopen("level_TA.out","w",stdout);
int n,m,i,j,stop,s;
in(n),in(m);
for(i=m;i--;){
in(s);
in(l[i]);
for(--s;--s;){
in(stop);
be[i][stop]=1;
}
in(r[i]);
for(j=l[i];j;--j)be[i][j]=1;
for(j=r[i];j<=n;++j)be[i][j]=1;
}
int etot=1;
for(i=n;i;--i){
btmp.set();
for(j=m;j--;)
if(l[j]<=i&&i<=r[j]&&be[j][i]){
//cout<<"Get:"<<j<<endl;
btmp&=be[j];
}
for(j=n;j;--j)
if(~btmp[j]){
next[etot]=ptr[i],ptr[i]=etot,succ[etot++]=j;
//cout<<i<<"->"<<j<<":"<<ptr[i]<<"->"<<next[etot-1]<<endl;
++ru[j];
}
}
int top=0;
for(i=n;i;--i)
if(ru[i]==0){
stack[top++]=i;
level[i]=1;
//cout<<"First into stack:"<<i<<endl;
}
int nowlevel;
while(top--){
nowlevel=level[stack[top]];
//cout<<"----"<<stack[top]<<"-----\n";
for(i=ptr[stack[top]];i;i=next[i]){
level[succ[i]]=max(level[succ[i]],nowlevel+1);
//cout<<i<<":"<<nowlevel+1<<"->"<<succ[i]<<endl;
if(--ru[succ[i]]==0)stack[top++]=succ[i];
}
}
printf("%d\n",*max_element(level+1,level+n+1));
}

code(对偶转换):

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
inline void in(int &x){
char c=getchar();
while(c<'0'||c>'9')c=getchar();
x=0;
for(;c>='0'&&c<='9';c=getchar())x=x*10+(c^'0');
}
int num[1005][1005],stop[1005][1005];
int stack[1005];
int next[1000005],ptr[1005],succ[1000005],ru[1005],etot=1;
int level[1005];
inline void addedge(int u,int v){
next[etot]=ptr[u],ptr[u]=etot,++ru[v],succ[etot++]=v;
}
int main(){
freopen("level2013.in","r",stdin);
freopen("level2013.out","w",stdout);
int n,m,i,j,k,tmp;
in(n),in(m);
++m;
for(i=n;i;--i)num[0][i]=stop[0][i]=i;
stop[0][0]=n;
for(i=m;--i;){
in(stop[i][0]);
for(j=1,k=1;j<=stop[i][0];++j)
for(in(stop[i][j]);k<stop[i][j];++k)
num[i][k]=j-1;
--j;
while(k<=n)num[i][k++]=j;
}
int l,r;
for(i=m;i--;)
for(j=i;j--;){
l=max(stop[i][1],stop[j][1])-1;
r=min(stop[i][stop[i][0]],stop[j][stop[j][0]]);
if(l<=r)
if(num[i][r]-num[i][l]>num[j][r]-num[j][l])addedge(i,j);
else if(num[i][r]-num[i][l]<num[j][r]-num[j][l])addedge(j,i);
}
int top=0;
for(i=m;i--;)
if(!ru[i]){
stack[top++]=i;
level[i]=1;
}
int nowlevel;
while(top--){
nowlevel=level[stack[top]]+1;
for(i=ptr[stack[top]];i;i=next[i]){
level[succ[i]]=max(level[succ[i]],nowlevel);
if(!--ru[succ[i]])stack[top++]=succ[i];
}
}
printf("%d\n",*max_element(level,level+m));
}

[NOIP2013]车站分级 解题报告的更多相关文章

  1. [NOIP2013 花匠] 新人解题报告

    本来按照老师的要求,我学OI的第一份解题报告应是在寒假完成的关于数据结构的基础题,但由于身体原因当时未能完成,那么就在省选赛前临时写几篇吧…… 题目描述 花匠栋栋种了一排花,每株花都有自己的高度.花儿 ...

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

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

  3. noip2013 车站分级

    题目描述 一条单向的铁路线上,依次有编号为 1, 2, …, n1,2,…,n的 nn个火车站.每个火车站都有一个级别,最低为 11 级.现有若干趟车次在这条线路上行驶,每一趟都满足如下要求:如果这趟 ...

  4. 题解【洛谷P1983】[NOIP2013]车站分级

    题面 题解 不难想到拓扑排序 于是每一个等级高的向等级低的连一条边 考虑拓扑排序过程中的分层 对于每个点进行分层 于是答案就是这些点中的最大层数 然后就会RE 发现我们多连了一些重复的边 用一个标记数 ...

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

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

  6. 习题:codevs 1035 火车停留解题报告

    本蒟蒻又来写解题报告了.这次的题目是codevs 1035 火车停留. 题目大意就是给m个火车的到达时间.停留时间和车载货物的价值,车站有n个车道,而火车停留一次车站就会从车载货物价值中获得1%的利润 ...

  7. $HNOI\ 2010$ 解题报告

    HNOI 2010 解题报告 0. HNOI2010 AC代码包下载地址 注: 戳上面的标题中的'地址' 下载 代码包, 戳下面每一题的文件名 可进入 题目链接. 每一题 对应代码的文件名 我在 每一 ...

  8. 洛谷P1983车站分级

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

  9. CH Round #56 - 国庆节欢乐赛解题报告

    最近CH上的比赛很多,在此会全部写出解题报告,与大家交流一下解题方法与技巧. T1 魔幻森林 描述 Cortana来到了一片魔幻森林,这片森林可以被视作一个N*M的矩阵,矩阵中的每个位置上都长着一棵树 ...

随机推荐

  1. PHP DES-ECB加密对接Java解密

    最近公司有个业务,需要对接第三方接口,但是参数是需要加密的,对方也只提供了一个java的demo,在网上到处搜索,没有找到直接就能用的方法,后来还是跟公司的Android工程师对接出来的,在这里记录一 ...

  2. Node实现简单的注册时后端的MVC模型架构

    实现一个简单的注册界面后端MVC模型架构 第一步:在生成的express框架的app.js中添加一个路由,代码如下:var api = require('./routes/api'); app.use ...

  3. 【C#】C#托付和事件的实例解说

    using System; namespace delegate_event { // 定义一个猫类 class Cat { // 定义一个名字字段 private string name; // 创 ...

  4. FZU--2188--过河(bfs暴力条件判断)

    过河I Time Limit: 3000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u Submit Status De ...

  5. POJ 1636 DFS+DP

    思路: 先搜索出来如果选这个点 其它哪些点必须选 跑个背包就好了 //By SiriusRen #include <cstdio> #include <cstring> #in ...

  6. 【Linux下自定义Shell终端提示符】

    目录 基本转义符 字体颜色 背景颜色 移动光标 @ Linux系统终端提示符的特征由系统环境变量 PS1(Prompt String One)定义. 我们可以通过命令echo $PS1来查看当前设置, ...

  7. 摄像头驱动——V4L2框架分析

    一.概述 Video for Linux 2,简称V4l2,是Linux内核中关于视频设备的内核驱动框架,为上层的访问底层的视频设备提供了统一的接口. 摄像头驱动是属于字符设备驱动程序.(分析linu ...

  8. Yeslab 华为安全HCIE-第七门-Agile Controlle

    课程目录:   华为安全HCIE-第七门-Agile Controller(12篇)\1_aglie_controller产品亮点讲解.avi 华为安全HCIE-第七门-Agile Controlle ...

  9. python全栈_day01

    计算机容量 1位 = 1bit  8bit = 1byte = 1字节      1024bytes = 1kbytes =1KB  1024个字符,小文档 ,几百k可以表示一张图片  1024KB ...

  10. PHP的数组分为两种类型,一种是索引数组,一种是关联数组。有如下关联数组,我们如何获取它的第一个key和value呢?

    示例:$items=array('name'=>'sjm','age'=>'26','sex' => '男','location'=>'北京'); //当然用循环然后break ...