【BZOJ3832】[POI2014]Rally(拓扑排序,动态规划)
【BZOJ3832】[POI2014]Rally(拓扑排序,动态规划)
题面
题解
这题好强啊,感觉学了好多东西似的。
首先发现了一个图画的很好的博客,戳这里
然后我来补充一下这题到底怎么做。
首先这个图是一个\(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(拓扑排序,动态规划)的更多相关文章
- BZOJ3832: [Poi2014]Rally(拓扑排序 堆)
题意 题目链接 Sol 最直观的思路是求出删除每个点后的最长路,我们考虑这玩意儿怎么求 设\(f[i]\)表示以\(i\)结尾的最长路长度,\(g[i]\)表示以\(i\)开始的最长路长度 根据DAG ...
- BZOJ3832[Poi2014]Rally——权值线段树+拓扑排序
题目描述 An annual bicycle rally will soon begin in Byteburg. The bikers of Byteburg are natural long di ...
- 【BZOJ-3832】Rally 拓扑序 + 线段树 (神思路题!)
3832: [Poi2014]Rally Time Limit: 20 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 168 Solved: ...
- bzoj 1093 最大半连通子图 - Tarjan - 拓扑排序 - 动态规划
一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任意两点u,v,存在一条u到v的有向路径或者从v到u的有向路径.若G'=(V ...
- Luogu3953 NOIP2017逛公园(最短路+拓扑排序+动态规划)
跑一遍dij根据最短路DAG进行拓扑排序,按拓扑序dp即可.wa了三发感觉非常凉. #include<iostream> #include<cstdio> #include&l ...
- BZOJ3832 [Poi2014]Rally 【拓扑序 + 堆】
题目链接 BZOJ3832 题解 神思路orz,根本不会做 设\(f[i]\)为到\(i\)的最长路,\(g[i]\)为\(i\)出发的最长路,二者可以拓扑序后\(dp\)求得 那么一条边\((u,v ...
- BZOJ3832 : [Poi2014]Rally
f[0][i]为i出发的最长路,f[1][i]为到i的最长路 新建源汇S,T,S向每个点连边,每个点向T连边 将所有点划分为两个集合S与T,一开始S中只有S,其它点都在T中 用一棵线段树维护所有连接属 ...
- 并不对劲的bzoj3832: [Poi2014]Rally
传送门-> 这题的原理看上去很神奇. 称拓扑图中入度为0的点为“起点”,出度为0的点为“终点”. 因为“起点”和“终点”可能有很多个,算起来会很麻烦,所以新建“超级起点”S,向所有点连边,“超级 ...
- 【BZOJ1471】不相交路径 题解(拓扑排序+动态规划+容斥原理)
题目描述 在有向无环图上给你两个起点和终点分别为$a,b,c,d$.问有几种路径方案使得能从$a$走到$b$的同时能从$c$走到$d$,且两个路径没有交点. $1\leq n\leq 200,1\le ...
- [luogu3573 POI2014] RAJ-Rally (拓扑排序 权值线段树)
传送门 Solution 在DAG中我们可以\(O(n)\)预处理\(Ds(u)\)表示从u表示以s为起点的最长路\(Dt(u)\)表示以u为终点的最长路,那么经过\((u,v)\)的最长路即为\(D ...
随机推荐
- ABC Tech Day(2018.08.11)
时间:2018.07.24地点:北京中关村创业大街车库咖啡
- 大数据入门第十六天——流式计算之storm详解(三)集群相关进阶
一.集群提交任务流程分析 1.集群提交操作 参考:https://www.jianshu.com/p/6783f1ec2da0 2.任务分配与启动流程 参考:https://www.cnblogs.c ...
- tensorflow batch
这两天一直在看tensorflow中的读取数据的队列,说实话,真的是很难懂.也可能我之前没这方面的经验吧,最早我都使用的theano,什么都是自己写.经过这两天的文档以及相关资料,并且请教了国内的师弟 ...
- 与Web交互可用的图片Base64编码
#ifndef ___BASE64_H___ #define ___BASE64_H___ #include <string> using namespace std; class CBa ...
- [CF1010E]Store[kd-tree]
题意 有一个长方体,不知道它的位置,给出 \(n\) 个一定在长方体内的点和 \(m\) 个一定不在的点,有 \(k\) 次询问,每次询问一个点是否 在.不在.不确定 在长方体内. \(n\leq 1 ...
- C#杂乱知识汇总
:first-child{margin-top:0!important}.markdown-body>:last-child{margin-bottom:0!important}.markdow ...
- HTML 表格实例
1.表格这个例子演示如何在 HTML 文档中创建表格. <p>每个表格由 table 标签开始.</p><p>每个表格行由 tr 标签开始.</p>&l ...
- Docker原理探究
问题思考:-------------------------------------Docker浅显原理理解-------------------------------------P1. ubunt ...
- GitHubDesktop权限问题解决办法
Desktop对于管理仓库非常方便.实用 很多人实用Desktop将仓库项目clone到本地 但是更新后同步时出现了如下权限错误: Error Authentication failed. You m ...
- sqlserver批量删除字段 msrepl_tran_version
屁话不多说. 原因: msrepl_tran_version由于有非空约束.所以不能直接删除. --###############################################--1 ...