【bzoj3832】Rally
Description
给你一个DAG,每条边长度都是\(1\),请找一个点满足删掉这个点之后剩余图中的最长路最短
Solution
这题的话感觉思路挺妙的
因为要涉及到删点操作,所以我们肯定不能通过直接的方法来算最长路,然后因为这题没有固定的起点和终点并且是一个DAG,所以有一个比较简单粗暴的处理方法就是像网络流一样建一个超级源\(S\)和一个超级汇\(T\),每个点都从\(S\)连一条长度为\(0\)的边,每个点都向\(T\)连一条长度为\(0\)的边
我们记\(f[i]\)表示从\(S\)到\(i\)点的最长路,记\(g[i]\)表示从\(i\)点到\(T\)点的最长路,这两个东西都可以按拓扑序转移直接dp出来(正反各来一次就好了),那么我们考虑一条边\((u,v)\)的贡献(也就是钦定要经过这条边的最长路)为\(f[u]+1+g[v]\),那么最长路的问题就变成了求边贡献的最大值
这个时候,考虑\(S\)到\(T\)的一个割(注意:这里不一定是最小割!只是一个普通的割即可),那么根据其定义,所有从\(S\)到\(T\)的路径必定经过割集中的最少一条边,也就是说,如果我们将\(f[u]+1+g[v]\)看成原图中\((u,v)\)这条边的边权,将\((S,i)\)的边权看成\(f[i]\),\((i,T)\)的边权看成\(g[i]\),割集中边权的最大值便是我们需要的答案
那么现在我们只要知道删掉一个点之后,剩余图中\(S\)到\(T\)的一个割就可以知道删掉这个点的答案了,至此我们已经完成了问题的转化,现在的问题是我们怎么维护这个割集
我们考虑用一个数据结构来快速获得边权最大值(线段树或者堆都ok)
假设一开始我们先把所有的\((i,T)\)的边全部断掉(这显然是一个可行的割),也就是先将所有的\(g[i]\)丢进数据结构里面,现在考虑删掉一个点\(x\)的影响:所有拓扑序在\(x\)之后的点的\(f\)值可能会被影响,所有拓扑序在\(x\)之前的点的\(g\)值可能会被影响,这个时候为了保证正确性我们应该将当前割集中可能会被改变边权的边全部删掉
但是这样怎么保证当前最大值一定在数据结构里面呢?这里需要一点关于操作顺序的技巧,下面先将过程讲一下:
我们考虑按照拓扑序从小到大依次计算删除这个点之后的最长路,对于当前枚举到的点\(x\),我们进行如下操作:
1、将\((x,T)\)这条边删掉,将所有的\((u,x)\)删掉(如果本来就没有就不进行操作)
2、统计当前割集中边权的最大值,更新答案
3、将\((S,x)\)这条边加入割集,将所有的\((x,v)\)加入割集
具体一点的话就是,首先\(1\)操作就是将割集中所有与\(x\)有关的边全部删掉,\(2\)不用说,关键是\(3\)操作,为什么我们还原割集的时候不是将\(1\)操作中删除的边加回进去呢?
因为我们是按照拓扑序从小到大删点的,根据我们前面分析出来的删点影响,在删除后面的点的时候,\(g[x]\)是可能会被影响的值(转移过来的边可能会被删掉),因此为了保证正确性我们不能将其留在割集中,同时为了保证这是一个割集,相对应的边权不会被影响到并且效果类似的\((S,x)\)就应该被加入割集,同样的道理\((u,x)\)的边权中的\(g[x]\)可能会被影响所以要删掉,然后为了保证一定是一个割集所以要加入\((x,v)\)这类边
那么会不会出现有的边的贡献作为答案没有被统计的情况呢?这个。。是不会的因为如果说\((u,x)\)这类边的贡献是答案的话,一定会在前面被计算到
然后这题就十分愉快地做完啦ovo时间复杂度\(O(nlogn)\)
代码大概长这个样子
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const int N=500010,M=1000010,SEG=N*4,inf=2147483647;
struct xxx{
int y,nxt;
}a[M*2];
queue<int> q;
int h1[N],h[N],in[N],out[N],f[N],g[N];
int rec[N];
int n,m,tot,ans,ansnode;
namespace Seg{/*{{{*/
int ch[SEG][2],mx[SEG],cnt[SEG];
int n,tot;
void pushup(int x){mx[x]=max(mx[ch[x][0]],mx[ch[x][1]]);}
void _build(int x,int l,int r){
mx[x]=-1;
if (l==r) return;
int mid=l+r>>1;
ch[x][0]=++tot; _build(ch[x][0],l,mid);
ch[x][1]=++tot; _build(ch[x][1],mid+1,r);
}
void build(int _n){tot=1; n=_n; _build(1,1,n);}
void _insert(int x,int d,int lx,int rx,int delta){
if (lx==rx){
cnt[x]+=delta;
if (cnt[x]>0) mx[x]=lx;
else cnt[x]=0,mx[x]=-1;
return;
}
int mid=lx+rx>>1;
if (d<=mid) _insert(ch[x][0],d,lx,mid,delta);
else _insert(ch[x][1],d,mid+1,rx,delta);
pushup(x);
}
void insert(int d,int delta){_insert(1,d,1,n,delta);}
int query(){return mx[1];}
}/*}}}*/
void add(int x,int y){
a[++tot].y=y; a[tot].nxt=h[x]; h[x]=tot;
a[++tot].y=x; a[tot].nxt=h1[y]; h1[y]=tot;
}
void prework(){
int u,v;
while (!q.empty()) q.pop();
for (int i=1;i<=n;++i)
if (!in[i]) q.push(i),f[i]=0;
rec[0]=0;
while (!q.empty()){
v=q.front(); q.pop(); rec[++rec[0]]=v;
for (int i=h[v];i!=-1;i=a[i].nxt){
u=a[i].y;
f[u]=max(f[u],f[v]+1);
--in[u];
if (!in[u]) q.push(u);
}
}
for (int i=1;i<=n;++i)
if (!out[i]) q.push(i),g[i]=0;
while (!q.empty()){
v=q.front(); q.pop();
for (int i=h1[v];i!=-1;i=a[i].nxt){
u=a[i].y;
g[u]=max(g[u],g[v]+1);
--out[u];
if (!out[u]) q.push(u);
}
}
}
void solve(){
int x,u,tmp;
ans=inf; ansnode=0;
Seg::build(n+1);
for (int i=1;i<=n;++i) Seg::insert(g[i]+1,1);
for (int i=1;i<=n;++i){
x=rec[i];
Seg::insert(g[x]+1,-1);
for (int j=h1[x];j!=-1;j=a[j].nxt){
u=a[j].y;
Seg::insert(f[u]+1+g[x]+1,-1);
}
tmp=Seg::query();
if (ans>tmp)
ans=tmp,ansnode=x;
Seg::insert(f[x]+1,1);
for (int j=h[x];j!=-1;j=a[j].nxt){
u=a[j].y;
Seg::insert(f[x]+1+g[u]+1,1);
}
}
printf("%d %d\n",ansnode,ans-1);
}
int main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
#endif
int x,y;
scanf("%d%d",&n,&m);
memset(h,-1,sizeof(h));
memset(h1,-1,sizeof(h1));
tot=0;
for (int i=1;i<=m;++i){
scanf("%d%d",&x,&y);
add(x,y);
++in[y]; ++out[x];
}
prework();
solve();
}
【bzoj3832】Rally的更多相关文章
- 【BZOJ-3832】Rally 拓扑序 + 线段树 (神思路题!)
3832: [Poi2014]Rally Time Limit: 20 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 168 Solved: ...
- 【BZOJ3832】[POI2014]Rally(拓扑排序,动态规划)
[BZOJ3832][POI2014]Rally(拓扑排序,动态规划) 题面 BZOJ,权限题 洛谷 题解 这题好强啊,感觉学了好多东西似的. 首先发现了一个图画的很好的博客,戳这里 然后我来补充一下 ...
- Python高手之路【六】python基础之字符串格式化
Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...
- 【原】谈谈对Objective-C中代理模式的误解
[原]谈谈对Objective-C中代理模式的误解 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这篇文章主要是对代理模式和委托模式进行了对比,个人认为Objective ...
- 【原】FMDB源码阅读(三)
[原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...
- 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新
[原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...
- 【调侃】IOC前世今生
前些天,参与了公司内部小组的一次技术交流,主要是针对<IOC与AOP>,本着学而时习之的态度及积极分享的精神,我就结合一个小故事来初浅地剖析一下我眼中的“IOC前世今生”,以方便初学者能更 ...
- Python高手之路【三】python基础之函数
基本数据类型补充: set 是一个无序且不重复的元素集合 class set(object): """ set() -> new empty set object ...
- Python高手之路【一】初识python
Python简介 1:Python的创始人 Python (英国发音:/ˈpaɪθən/ 美国发音:/ˈpaɪθɑːn/), 是一种解释型.面向对象.动态数据类型的高级程序设计语言,由荷兰人Guido ...
随机推荐
- 理解粒子滤波(particle filter)
1)初始化阶段-提取跟踪目标特征 该阶段要人工指定跟踪目标,程序计算跟踪目标的特征,比如可以采用目标的颜色特征.具体到Rob Hess的代码,开始时需要人工用鼠标拖动出一个跟踪区域,然后程序自动计算该 ...
- tomcat安装及使用详解
常用软件安装及使用目录 资料链接:https://pan.baidu.com/s/1XOUlneFqt-_1tOLSmc-E1g 网盘分享的文件在此 1. Tomcat简介 Tomcat是一个 ...
- JavaWeb项目通过调用cmd实现备份数据库的功能
1.别急着上车,先测试一下能否成功调用cmd,可以尝试通过cmd命令打开计算器,代码如下: 2.能成功打开计算器后,证明调用cmd的方法是没错的,现在把cmd命令字符串改成我们备份数据库的 命 ...
- 【探路者】final贡献分配
[探路者]组成员及各位博客地址. 1蔺依铭:http://www.cnblogs.com/linym762/ 2张恩聚:http://www.cnblogs.com/zej87/ 3米赫:http: ...
- 在js中保存数据
localStorage: localStorage.setItem("key", "value"); localStorage.getItem("k ...
- 第三次博客作业JSF
JSF规格化设计发展史以及为什么得到人们重视 查阅了n多资料但是仍然没找到. 就说一些jsf的优势吧. 优势: (1)UI组件 (2)事件驱动模式 (3)用户界面到业务逻辑的直接映射 (4)程序 ...
- java第四次实验报告
课程:Java程序与设计 班级:1352 姓 名:池彬宁 小组成员: 20135212池彬宁 20135208贺邦 学号:20135212 成绩: 指导教师:娄嘉鹏 ...
- 【CSAPP笔记】7. 汇编语言——过程调用
一个过程调用包括将数据(以参数和返回值的形式)与控制从代码的一部分传递到另一部分.除此之外,在进入时为过程的局部变量分配空间,在退出的时候释放这些空间.数据传递.局部变量的分配和释放通过操纵程序栈来实 ...
- 西门子S7系列PLC的主要种类及应用软件
德国西门子(SIEMENS)公司生产的可编程序控制器在我国的应用也相当广泛,在冶金.化工.印刷生产线等领域都有应用.西门子(SIEMENS)公司的PLC产品包括LOGO,S7-200,S7-300,S ...
- 确保你想要修改的char*是可以修改的
void change(char *source) { source[] = 'D'; cout<<source<<endl; } 考虑一下,你有这么一个函数change它的作 ...