【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. js实现60秒倒计时效果(使用了jQuery)

    今天碰到要实现一个类似那种短信验证码60秒倒计时的需求,好久不写js,有点手生.把代码记录下,方便后续查阅. 这里我用了jQuey,毕竟写起来简洁点.下面直接看效果和代码. 一.效果          ...

  2. Python 语言简介

    Python是一种计算机程序设计语言.你可能已经听说过很多种流行的编程语言,比如非常难学的C语言,非常流行的Java语言,适合初学者的Basic语言,适合网页编程的JavaScript语言等等. 那P ...

  3. 【php增删改查实例】第九节 - 部门管理模块(模糊查询)

    给datagrid添加一个工具栏. 效果: 模糊查询部门名称. 接下来,在工具栏区域画一个input框: <div id="toolbar" style="padd ...

  4. Centos7下python3安装ipython

    一.通过压缩包安装ipython 1.下载ipython安装包 [root@localhost ~]# wget https://pypi.python.org/packages/79/63/b671 ...

  5. Java过滤器与SpringMVC拦截器的差异学习笔记

    学习摘录地址:http://blog.csdn.net/chenleixing/article/details/44573495 今天学习和认识了一下,过滤器和SpringMVC的拦截器的区别,学到了 ...

  6. iOS开发面试题整理

    前言 本文借鉴整理了iOS高级开发常见的面试题,并且分博客一一分析,希望能和大家一起进步学习. 欢迎大家关注我的 Github

  7. idou老师教你学istio :基于角色的访问控制

    istio的授权功能,也称为基于角色的访问控制(RBAC),它为istio服务网格中的服务提供命名空间级别.服务级别和方法级别的访问控制.基于角色的访问控制具有简单易用.灵活和高性能等特性.本文介绍如 ...

  8. Apache访问验证方式

    Require all granted 允许所有请求访问资源 Require all denied 拒绝所有请求访问资源 Require env env-var [env-var] ... 当指定环境 ...

  9. Daily Scrum 12.22

    姓名 上周末任务 今日任务 刘垚鹏 完善和增加quiz页面的过滤功能 完善和增加quiz页面的过滤功能 王骜 对问答功能的修复 对问答功能的修复 林旭鹏 存储文件路径太长导致bug修复 存储文件路径太 ...

  10. 第五次Scrum meeting

    第五次Scrum meeting 会议内容: 连接方面:确定封装成json的文本格式,尽量在满足在线组和手机客户端两组的情况下,降低自身的难度 测试方面:进行新一轮测试,主要测试程序的稳定性和可靠性, ...