题意:

给出$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. (DCloud)用这个来写H5,好像好厉害的样子哦

    HBuilder: http://www.dcloud.io MUI: http://dev.dcloud.net.cn/mui/getting-started/ http://dev.dcloud. ...

  2. js检查浏览器是否处于隐身模式

    网上大部分的文章写隐身模式下 localStorage 对象不可用,直接以 localStorage 能否写入来判断浏览器是否处于隐身模式其实是错的,在隐身模式下localStorage也是能使用的, ...

  3. 【RF库Collections测试】Get From Dictionary

    Name:Get From DictionarySource:Collections <test library>Arguments:[ dictionary | key ]Returns ...

  4. docker学习-docker仓库

    docker仓库中心:https://hub.docker.com/ 网易蜂巢仓库中心:https://c.163.com/hub#/m/home/

  5. Linux tty 命令

    终端:终端(Terminal)也称终端设备,是计算机网络中处于网络最外围的设备(如键盘 .打印机 .显示器等),主要用于用户信息的输入以及处理结果的输出 TTY:TTY 是 Teletype(电传打字 ...

  6. js正则函数match、exec、test、search、replace、split使用介绍集合,学习正则表达式的朋友可以参考下。

    match 方法 使用正则表达式模式对字符串执行查找,并将包含查找的结果作为数组返回. stringObj.match(rgExp) 参数 stringObj 必选项.对其进行查找的 String 对 ...

  7. 动态调整UITableViewCell高度的实现方法

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPa ...

  8. Android 使用RadioGroup和RadioButton实现单选效果

    RadioButton和CheckBox的区别:CheckBox选中之后可以直接取消,RadioButton选中之后不能直接取消,所以一般情况下不建议单独使用.1.RadioGroup:RadioBu ...

  9. [分享]方便的 windbg 命令 - !list

    Windows 内部的各种结构通常都会由双向链表串起来,用 !list 命令查看这些结构非常方便. 比如查看系统中的所有进程: lkd> !list -t nt!_LIST_ENTRY.Flin ...

  10. with操作符损耗性能的原因

    当函数运行是,创建一个[[scope]]指向的被称为作用域链的可变对象集合,作用域链的最前端是一个包含所有的局部变量.参数.this等的被称为“激活对象”的对象. 在标示符查找的过程中,从作用域的最前 ...