Portal -->bzoj3832

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的更多相关文章

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

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

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

    [BZOJ3832][POI2014]Rally(拓扑排序,动态规划) 题面 BZOJ,权限题 洛谷 题解 这题好强啊,感觉学了好多东西似的. 首先发现了一个图画的很好的博客,戳这里 然后我来补充一下 ...

  3. Python高手之路【六】python基础之字符串格式化

    Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...

  4. 【原】谈谈对Objective-C中代理模式的误解

    [原]谈谈对Objective-C中代理模式的误解 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这篇文章主要是对代理模式和委托模式进行了对比,个人认为Objective ...

  5. 【原】FMDB源码阅读(三)

    [原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...

  6. 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新

    [原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...

  7. 【调侃】IOC前世今生

    前些天,参与了公司内部小组的一次技术交流,主要是针对<IOC与AOP>,本着学而时习之的态度及积极分享的精神,我就结合一个小故事来初浅地剖析一下我眼中的“IOC前世今生”,以方便初学者能更 ...

  8. Python高手之路【三】python基础之函数

    基本数据类型补充: set 是一个无序且不重复的元素集合 class set(object): """ set() -> new empty set object ...

  9. Python高手之路【一】初识python

    Python简介 1:Python的创始人 Python (英国发音:/ˈpaɪθən/ 美国发音:/ˈpaɪθɑːn/), 是一种解释型.面向对象.动态数据类型的高级程序设计语言,由荷兰人Guido ...

随机推荐

  1. PASSWORD MySQL 5.6.21-1ubuntu14.04_amd64

    /***************************************************************************** The main idea is that ...

  2. 【一】,python简单爬虫实现

    一: 1.获取当前页的课程名称,地址:https://www.ichunqiu.com/courses/webaq 2.选取其中一门课程名称查看源代码: 代码如下: <p class=" ...

  3. Go文件右键编译

    辛辛苦苦写好了.go文件 发现编译还得敲命令才行,或许配置一个好用点的IDE环境可以解决 但是有时候实在不想开IDE 于是在右键添加了一个编译功能 首先保证go相关的环境变量配置正确 Windows ...

  4. halt命令详解

    基础命令学习目录首页 原文链接:https://www.jb51.net/LINUXjishu/57947.html 名称:halt 使用权限:系统管理者 halt 使用方式:halt [-n] [- ...

  5. lspci命令详解

    基础命令学习目录首页 最近经常用到 lspci -nn | grep Eth 命令,需要学习下PCI总线,找到一篇文章,虽然也是转载,但写的较清晰,再次转载下. http://blog.csdn.ne ...

  6. 通过NPM快速发布你的NodeJS模块(组件包)

    1.更新 NPM - [ npm install -g npm | 该步骤可选:最好使用新版本] 楼主当前版本号 2.6.1 ,如果更新报错,可以尝试 国内淘宝镜像 $ npm -v 2.6.1 // ...

  7. “Hello World!“”团队第七周召开的第三次会议

    今天是我们团队“Hello World!”团队第七周召开的第三次会议.博客内容: 一.会议时间 二.会议地点 三.会议成员 四.会议内容 五.todo list 六.会议照片 七.燃尽图 八.代码 一 ...

  8. TeamWork#3,Week5,Introduction to the "take-away" Sale Selection Project

    一.NABCD 1.N(Need 需求) 当今社会生活节奏快,很多大学生.上班族叫外卖比较普遍,外卖生意异常火爆.最近美团.饿了么等外卖服务竞争激烈,产生了大量外卖优惠信息.而网络上外卖信息比较混乱, ...

  9. IO异常 的处理

    package com.throwsss; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFou ...

  10. 第二次作业利用java语言编写计算器进行四则运算

    随着第一次作业的完成,助教 牛老师又布置了第二次作业:用java语言编写一个程序然后进行四则运算用户用键盘输入一个字符来结束程序显示统计结果.一开始看到这个题目我也着实吓了一跳 因为不知道如何下手而且 ...