【BZOJ3832】[POI2014]Rally(拓扑排序,动态规划)

题面

BZOJ,权限题

洛谷

题解

这题好强啊,感觉学了好多东西似的。

首先发现了一个图画的很好的博客,戳这里

然后我来补充一下这题到底怎么做。

首先这个图是一个\(DAG\),我们对其进行拓扑排序,设\(f[i]\)表示以\(i\)开头的最长链长度,\(g[i]\)表示以\(i\)结尾的最长链长度,那么经过某条边\(u\rightarrow v\)的边贡献的最长路的贡献就是\(g[u]+f[v]+1\)。

我们发现,如果我们删除某一个点\(x\),那么我们必定能够把整个图分成两个部分,左侧我们认为是拓扑序小于\(x\)的点集,右侧是拓扑序大于\(x\)的点集,那么最终的答案显然是从左侧的某一个点连向右侧的某一个点能够贡献的最长链。所以我们只需要动态的维护左侧连向右侧的边的贡献就好了。我们先假设所有点都在右侧,按照拓扑序依次把所有点移到左侧就好了。我们可以直接在这个过程中统计答案。首先我们把所有左侧连向当前点的边的贡献全部删掉,然后统计一下答案,然后再把这个点连向右侧的边的贡献全部加入进来。当然,不仅仅只有边的贡献,显然\(f,g\)两个数组可以产生贡献,左侧的点产生\(g\)的贡献,右侧产生\(f\)的贡献,也和边的贡献一起丢进什么数据结构维护一下就好了。因为每条边只会加一次,删一次,所以复杂度是\(O((n+m)log)\)的。

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
#define MAX 500500
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
struct Heap
{
priority_queue<int> Q1,Q2;
void push(int x){Q1.push(x);}
void del(int x){Q2.push(x);}
bool empty(){while(!Q2.empty()&&Q1.top()==Q2.top())Q1.pop(),Q2.pop();return Q1.empty();}
int top(){if(empty())return 1e9;return Q1.top();}
}S;
int n,m,ans1=1e9,ans2;
struct Line{int v,next;}e[MAX<<2];
int h[MAX],cnt=1,dg[MAX];
inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;}
int Q[MAX],f[MAX],g[MAX];
void Topsort()
{
int he=1,t=0;
for(int i=1;i<=n;++i)if(!dg[i])Q[++t]=i;
while(he<=t)
{
int u=Q[he++];
for(int i=h[u];i;i=e[i].next)
if(i&1)if(!--dg[e[i].v])Q[++t]=e[i].v;
}
for(int u=1;u<=n;++u)
for(int i=h[Q[u]];i;i=e[i].next)
if(i&1)g[e[i].v]=max(g[e[i].v],g[Q[u]]+1);
for(int u=n;u>=1;--u)
for(int i=h[Q[u]];i;i=e[i].next)
if(i&1)f[Q[u]]=max(f[Q[u]],f[e[i].v]+1);
}
int main()
{
n=read();m=read();
for(int i=1,u,v;i<=m;++i)u=read(),v=read(),Add(u,v),Add(v,u),++dg[v];
Topsort();
for(int i=1;i<=n;++i)S.push(f[i]);
for(int j=1;j<=n;++j)
{
int u=Q[j];S.del(f[u]);
for(int i=h[u];i;i=e[i].next)
if(!(i&1))S.del(f[u]+g[e[i].v]+1);
int d=S.top();S.push(g[u]);
if(d<ans1)ans1=d,ans2=u;
for(int i=h[u];i;i=e[i].next)
if(i&1)S.push(g[u]+f[e[i].v]+1);
}
printf("%d %d\n",ans2,ans1);
return 0;
}

【BZOJ3832】[POI2014]Rally(拓扑排序,动态规划)的更多相关文章

  1. BZOJ3832: [Poi2014]Rally(拓扑排序 堆)

    题意 题目链接 Sol 最直观的思路是求出删除每个点后的最长路,我们考虑这玩意儿怎么求 设\(f[i]\)表示以\(i\)结尾的最长路长度,\(g[i]\)表示以\(i\)开始的最长路长度 根据DAG ...

  2. BZOJ3832[Poi2014]Rally——权值线段树+拓扑排序

    题目描述 An annual bicycle rally will soon begin in Byteburg. The bikers of Byteburg are natural long di ...

  3. 【BZOJ-3832】Rally 拓扑序 + 线段树 (神思路题!)

    3832: [Poi2014]Rally Time Limit: 20 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 168  Solved:  ...

  4. bzoj 1093 最大半连通子图 - Tarjan - 拓扑排序 - 动态规划

    一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任意两点u,v,存在一条u到v的有向路径或者从v到u的有向路径.若G'=(V ...

  5. Luogu3953 NOIP2017逛公园(最短路+拓扑排序+动态规划)

    跑一遍dij根据最短路DAG进行拓扑排序,按拓扑序dp即可.wa了三发感觉非常凉. #include<iostream> #include<cstdio> #include&l ...

  6. BZOJ3832 [Poi2014]Rally 【拓扑序 + 堆】

    题目链接 BZOJ3832 题解 神思路orz,根本不会做 设\(f[i]\)为到\(i\)的最长路,\(g[i]\)为\(i\)出发的最长路,二者可以拓扑序后\(dp\)求得 那么一条边\((u,v ...

  7. BZOJ3832 : [Poi2014]Rally

    f[0][i]为i出发的最长路,f[1][i]为到i的最长路 新建源汇S,T,S向每个点连边,每个点向T连边 将所有点划分为两个集合S与T,一开始S中只有S,其它点都在T中 用一棵线段树维护所有连接属 ...

  8. 并不对劲的bzoj3832: [Poi2014]Rally

    传送门-> 这题的原理看上去很神奇. 称拓扑图中入度为0的点为“起点”,出度为0的点为“终点”. 因为“起点”和“终点”可能有很多个,算起来会很麻烦,所以新建“超级起点”S,向所有点连边,“超级 ...

  9. 【BZOJ1471】不相交路径 题解(拓扑排序+动态规划+容斥原理)

    题目描述 在有向无环图上给你两个起点和终点分别为$a,b,c,d$.问有几种路径方案使得能从$a$走到$b$的同时能从$c$走到$d$,且两个路径没有交点. $1\leq n\leq 200,1\le ...

  10. [luogu3573 POI2014] RAJ-Rally (拓扑排序 权值线段树)

    传送门 Solution 在DAG中我们可以\(O(n)\)预处理\(Ds(u)\)表示从u表示以s为起点的最长路\(Dt(u)\)表示以u为终点的最长路,那么经过\((u,v)\)的最长路即为\(D ...

随机推荐

  1. 数据结构与算法之Stack(栈)的应用——用stack实现一个计算器-/bin/calc.dart

    计算器的bin/calc.dart 可执行代码: import 'dart:io'; import 'package:data_struct/stack/sample/calculator.dart' ...

  2. Sqlite 快速批量插入数据 测试

    public static int insertDbBatch() { string sql = ""; SQLiteConnection conn = new SQLiteCon ...

  3. 20155233 《网络对抗》Exp4 恶意代码分析

    使用schtasks指令监控系统运行 先在C盘目录下建立一个netstatlog.bat文件,用来将记录的联网结果格式化输出到netstatlog.txt文件中,netstatlog.bat内容为: ...

  4. 20155317王新玮《网络对抗》Exp2 后门原理与实践

    20155317王新玮<网络对抗>Exp2 后门原理与实践 一.实验内容 (1)使用netcat获取主机操作Shell,cron启动 (2)使用socat获取主机操作Shell, 任务计划 ...

  5. 4556: [Tjoi2016&Heoi2016]字符串

    4556: [Tjoi2016&Heoi2016]字符串 链接 分析: 首先可以二分这个长度.此时需要判断是否存在一个以b结尾的前缀,满足与[c,d]的lcp大于等于mid. 如果我们把串翻转 ...

  6. vuex实践之路——笔记本应用(二)

    上一篇我们简单介绍了vuex在此项目中的作用. 这次来理一下项目的整体思路. main.js上次看过了,首先看App.vue文件 我们引入了Toolbar.vue,NodeList.vue,Edito ...

  7. 移动端jq及zepto事件绑定

    最近做移动端网页,用到了zepto.js , 其大致用法跟 jquery 差不多,但是在时间绑定的时候被困了好久的坑. 这里说的主要是给未来元素绑定事件.未来元素:这里指的是通过 ajax 请求得到数 ...

  8. idea使用actiBPM插件中文乱码

    idea 安转activiti插件后,编辑流程图发现保存后中文乱码,并且idea的字符集(Settings—>Editor—>File Encodings)已经设置为UTF-8,流程图中中 ...

  9. Vue.js 相关知识(路由)

    1. 简介 路由,工作原理与路由器相似(路由器将网线总线的IP分发到每一台设备上),Vue中的路由根据用户在网页中的点击,将其引导到对应的页面. 2. 使用步骤 安装vue-router或者直接引入v ...

  10. 火狐浏览器之伪造IP地址

    前言: 前段时间,测试过程中需要伪造来源IP地址,百思不得其解,因而发现火狐浏览器的这个Modify Headers插件,十分好用,推荐给大家. 步骤: 1.安装插件Modify Headers 进入 ...