题意:

给出$DAG$,询问删掉哪个点之后最长路径最短

思路:

我们令$f[x]$表示从最远的点到达它的距离,$g[x]$表示它能够到达最远的点的距离

那么对于$(x -> y)$一条边来说,它所在的最长路径就是 $f[x] + 1 + g[y]$

我们按照拓扑序依次删点

我们发现此时删去一个点,那么可能存在的最长的路径是

和它同一层的点所在的路径,以及它前一层的点所在的路径,以及它后一层的点所在的路径

因为它只会影响到它前一层的点和后一层的点

那么我们删去它所有入边的贡献,以及它本身的$g[x]$的贡献

再更新答案后

我们加入它出边的贡献,以及它本身的$f[x]$的贡献

 #include <bits/stdc++.h>
using namespace std; #define N 500010
int n, m;
vector <int> G[][N];
int f[N], g[N]; namespace SEG
{
int cnt[N << ], Max[N << ];
void build(int id, int l, int r)
{
cnt[id] = Max[id] = ;
if (l == r)
return;
int mid = (l + r) >> ;
build(id << , l, mid);
build(id << | , mid + , r);
}
void update(int id, int l, int r, int pos, int v)
{
if (pos == ) return;
if (l == r)
{
cnt[id] += v;
if (cnt[id] > ) Max[id] = pos;
else Max[id] = ;
return;
}
int mid = (l + r) >> ;
if (pos <= mid) update(id << , l, mid, pos, v);
else update(id << | , mid + , r, pos, v);
Max[id] = max(Max[id << ], Max[id << | ]);
}
} int id[N], d[][N];
void Toposort()
{
id[] = ;
memset(f, , sizeof f);
memset(g, , sizeof g);
queue <int> q;
for (int i = ; i <= n; ++i)
if (d[][i] == )
q.push(i);
while (!q.empty())
{
int u = q.front(); q.pop();
id[++id[]] = u;
for (int v, it = , len = G[][u].size(); it < len; ++it)
{
v = G[][u][it];
if (--d[][v] == )
{
f[v] = f[u] + ;
q.push(v);
}
}
}
for (int i = ; i <= n; ++i)
if (d[][i] == )
q.push(i);
while (!q.empty())
{
int u = q.front(); q.pop();
for (int v, it = , len = G[][u].size(); it < len; ++it)
{
v = G[][u][it];
if (--d[][v] == )
{
g[v] = g[u] + ;
q.push(v);
}
}
}
} void Run()
{
while (scanf("%d%d", &n, &m) != EOF)
{
for (int i = ; i <= n; ++i)
G[][i].clear(), G[][i].clear();
memset(d, , sizeof d);
SEG::build(, , m);
for (int i = , u, v; i <= m; ++i)
{
scanf("%d%d", &u, &v);
G[][u].push_back(v); ++d[][v];
G[][v].push_back(u); ++d[][u];
}
Toposort();
for (int i = ; i <= n; ++i)
SEG::update(, , m, g[i], );
int Min = (int)1e9, pos = -;
for (int x, i = ; i <= n; ++i)
{
x = id[i];
for (int v, it = , len = G[][x].size(); it < len; ++it)
{
v = G[][x][it];
SEG::update(, , m, f[v] + + g[x], -);
}
SEG::update(, , m, g[x], -);
int now = SEG::Max[];
if (now < Min)
{
Min = now;
pos = x;
}
SEG::update(, , m, f[x], );
for (int v, it = , len = G[][x].size(); it < len; ++it)
{
v = G[][x][it];
SEG::update(, , m, f[x] + + g[v], );
}
}
printf("%d %d\n", pos, Min);
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

BZOJ:3832: [Poi2014]Rally的更多相关文章

  1. 【BZOJ】3832: [Poi2014]Rally

    题意 \(n(2 \le n \le 500000)\)个点\(m(1 \le m \le 1000000)\)条边的有向无环图,找到一个点,使得删掉这个点后剩余图中的最长路径最短. 分析 神题不会做 ...

  2. 3832: [Poi2014]Rally

    3832: [Poi2014]Rally 链接 分析: 首先可以考虑删除掉一个点后,计算最长路. 设$f[i]$表示从起点到i的最长路,$g[i]$表示从i出发到终点的最长路.那么经过一条边的最长路就 ...

  3. BZOJ 3832: [Poi2014]Rally

    Sol 线段树+拓扑序. 先把图的拓扑序搞出来,然后统计从起点到该点最长链,从该点到终点的最长链,然后建个起点终点,这里跟网络流很像,把它统一到一个有起点的图中,这里也要注意下细节处理.S,T的一个边 ...

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

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

  5. BZOJ:3441 乌鸦喝水

    bzoj:3441 乌鸦喝水 题目传送门 Description 一只乌鸦在自娱自乐,它在面前放了n个有魔力的水缸,水缸里装有无限的水. 他准备从第1个水缸飞到第n个水缸,共m次.在飞过一个水缸的过程 ...

  6. 【BZOJ】3835: [Poi2014]Supercomputer

    题意 \(n(1 \le 1000000)\)个点的有根树,\(1\)号点为根,\(q(1 \le 1000000)\)次询问,每次给一个\(k\),每一次可以选择\(k\)个未访问的点,且父亲是访问 ...

  7. 【BZOJ】3834: [Poi2014]Solar Panels

    http://www.lydsy.com/JudgeOnline/problem.php?id=3834 题意:求$max\{(i,j)\}, smin<=i<=smax, wmin< ...

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

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

  9. [POI2014]Rally

    OJ题号:BZOJ3832.洛谷3573 思路: 建立超级源汇$S$和$T$,DP求出分别以$S$和$T$为源点的最长路$diss$和$dist$. 对于每条边$i$,设定一个权值$w_i=diss_ ...

随机推荐

  1. Dubbo(二) -- Simple Monitor

    一.简介 dubbo-monitor-simple是dubbo提供的简单监控中心,可以用来显示接口暴露,注册情况,也可以看接口的调用明细,调用时间等. Simple Monitor挂掉不会影响到Con ...

  2. linux下串口调试工具/串口终端推荐: picocom(转)

    对于picocom, kermit, minicom, picocom 最简单易用,也完全符合我的使用需求. 安装(mint / ubuntu):$ sudo apt-get install pico ...

  3. 基于Cocos2d-x学习OpenGL ES 2.0系列——你的第一个三角形(1)

    前言 在本系列教程中,我会以当下最流行的2D引擎Cocos2d-x为基础,介绍OpenGL ES 2.0的一些基本用法.本系列教程的宗旨是OpenGL扫盲,让大家在使用Cocos2d-x过程中,知其然 ...

  4. 《C++ Primer Plus》第13章 类继承 笔记

    类继承通过使用已有的类(基类)定义新的来(派生类),使得能够根据需要修改编程代码.共有继承建立is-a关系,这意味着派生类对象也应该是某种基类对象.作为is-a模型的一部分,派生类继承基类的数据称源和 ...

  5. ExtJS 6.2 基础使用

    一. 安装: 下载两个压缩包:分别是 ext-6.2.0-gpl(这个是ExtJS 的SDK文件,创建新项目的时候需要用). SenchaCmd-6.5.2-windows-64bit (这个下载下来 ...

  6. 演示PostgreSQL的详细安装及配置图解

    右击文件选择以管理员身份运行 2 开始执行程序的安装 3 设置安装目录 4 设置数据的保存目录 5 设置数据库管理员密码,请牢记此密码. 6 设置端口号,选择默认的端口号即可 7 根据自己选择设置地区 ...

  7. xdebug和最重要的php调试技巧

    好几年没有写PHP代码了,最近写了一些.我比较厌烦php,主要是调试麻烦,要按无数次F5,经常刷出空白. 以前调试总是依赖于在代码中加入下面两行 error_reporting(E_ALL ^ E_N ...

  8. c++11实现异步定时器

    c++11提供了丰富的时间和线程操作函数,比如 std::this_thread::sleep, std::chrono::seconds等.可以利用这些来很方便的实现一个定时器.     定时器要求 ...

  9. HTML - 分页效果布局

    <p class="jcFY"> 显示 <select name="" id=""> <option valu ...

  10. OC开发_Storyboard——绘制和视图

    1.绘制 不要调用drawRect.调用setNeedsDisplay相当于告知系统视图需要重绘, 它会去调用drawRect,更新屏外缓冲器 2.UIBezierPath绘制图形,   设置图像op ...