3832: [Poi2014]Rally
3832: [Poi2014]Rally
分析:
首先可以考虑删除掉一个点后,计算最长路。
设$f[i]$表示从起点到i的最长路,$g[i]$表示从i出发到终点的最长路。那么经过一条边的最长路就是$f[u]+1+g[v]$。
删除一个点x后,会使一些路径没了。考虑这些路径的特点。我们它比x拓扑序小的设为集合S,拓扑序大的设为T。
1、如果以前的一条路径经过x,那么去掉x后,考虑如何去掉这些路径的影响。只需将x的入边删掉就行了。
2、那么如何统计新的答案,并且新的路径不能经过x。此处是一个有意思的地方,统计所有起点在S,终点在T的所有边,会发现所有经过这些边的路径都不会经过x。(这些路径中一般是起代替x的作用的,但是存在一些边并没有代替x,但是对答案不影响)。
那么做法就出来了:按照拓扑序删点,不断维护起点在S,终点在T的边,每条边权值为$f[u]+1+g[v]$,取最大值。
代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cctype>
#include<set>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef long long LL; inline int read() {
int x=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
} const int N = ;
int g[N], f[N], T[N << ], cnt[N << ], q[N], n; struct Edge{
int to[N << ], nxt[N << ], head[N], En, deg[N << ];
inline void add_edge(int u,int v) {
++En; to[En] = v, nxt[En] = head[u]; head[u] = En; deg[v] ++;
}
}Z, F; void solve() {
int L = , R = ;
for (int i = ; i <= n; ++i) if (F.deg[i] == ) q[++R] = i;
while (L <= R) {
int u = q[L ++];
for (int i = F.head[u]; i; i = F.nxt[i]) {
int v = F.to[i];
g[v] = max(g[v], g[u] + );
if (!(--F.deg[v])) q[++R] = v;
}
}
L = , R = ;
for (int i = ; i <= n; ++i) if (Z.deg[i] == ) q[++R] = i;
while (L <= R) {
int u = q[L ++];
for (int i = Z.head[u]; i; i = Z.nxt[i]) {
int v = Z.to[i];
f[v] = max(f[v], f[u] + );
if (!(--Z.deg[v])) q[++R] = v;
}
}
}
void update(int l,int r,int rt,int p,int v) {
if (l == r) {
cnt[rt] += v;
if (cnt[rt] > ) T[rt] = l;
else T[rt] = -, cnt[rt] = ;
return ;
}
int mid = (l + r) >> ;
if (p <= mid) update(l, mid, rt << , p, v);
else update(mid + , r, rt << | , p, v);
T[rt] = max(T[rt << ], T[rt << | ]);
}
int main() {
n = read();int m = read();
for (int i = ; i <= m; ++i) {
int x = read(), y = read();
Z.add_edge(x, y);
F.add_edge(y, x);
}
solve();
int ans = 1e9, pt;
for (int i = ; i <= n; ++i) update(, n, , g[i], );
for (int i = ; i <= n; ++i) {
int x = q[i];
for (int j = F.head[x]; j; j = F.nxt[j])
update(, n, , g[x] + f[F.to[j]] + , -);
update(, n, , g[x], -);
if (T[] < ans) ans = T[], pt = x;
for (int j = Z.head[x]; j; j = Z.nxt[j])
update(, n, , f[x] + g[Z.to[j]] + , );
update(, n, , f[x], );
}
cout << pt << " " << ans;
return ;
}
3832: [Poi2014]Rally的更多相关文章
- BZOJ 3832: [Poi2014]Rally
Sol 线段树+拓扑序. 先把图的拓扑序搞出来,然后统计从起点到该点最长链,从该点到终点的最长链,然后建个起点终点,这里跟网络流很像,把它统一到一个有起点的图中,这里也要注意下细节处理.S,T的一个边 ...
- 【BZOJ】3832: [Poi2014]Rally
题意 \(n(2 \le n \le 500000)\)个点\(m(1 \le m \le 1000000)\)条边的有向无环图,找到一个点,使得删掉这个点后剩余图中的最长路径最短. 分析 神题不会做 ...
- BZOJ:3832: [Poi2014]Rally
题意: 给出$DAG$,询问删掉哪个点之后最长路径最短 思路: 我们令$f[x]$表示从最远的点到达它的距离,$g[x]$表示它能够到达最远的点的距离 那么对于$(x -> y)$一条边来说,它 ...
- 【BZOJ3832】[POI2014]Rally(拓扑排序,动态规划)
[BZOJ3832][POI2014]Rally(拓扑排序,动态规划) 题面 BZOJ,权限题 洛谷 题解 这题好强啊,感觉学了好多东西似的. 首先发现了一个图画的很好的博客,戳这里 然后我来补充一下 ...
- BZOJ3832[Poi2014]Rally——权值线段树+拓扑排序
题目描述 An annual bicycle rally will soon begin in Byteburg. The bikers of Byteburg are natural long di ...
- BZOJ3832 : [Poi2014]Rally
f[0][i]为i出发的最长路,f[1][i]为到i的最长路 新建源汇S,T,S向每个点连边,每个点向T连边 将所有点划分为两个集合S与T,一开始S中只有S,其它点都在T中 用一棵线段树维护所有连接属 ...
- [POI2014]Rally
OJ题号:BZOJ3832.洛谷3573 思路: 建立超级源汇$S$和$T$,DP求出分别以$S$和$T$为源点的最长路$diss$和$dist$. 对于每条边$i$,设定一个权值$w_i=diss_ ...
- BZOJ3832: [Poi2014]Rally(拓扑排序 堆)
题意 题目链接 Sol 最直观的思路是求出删除每个点后的最长路,我们考虑这玩意儿怎么求 设\(f[i]\)表示以\(i\)结尾的最长路长度,\(g[i]\)表示以\(i\)开始的最长路长度 根据DAG ...
- BZOJ3832 [Poi2014]Rally 【拓扑序 + 堆】
题目链接 BZOJ3832 题解 神思路orz,根本不会做 设\(f[i]\)为到\(i\)的最长路,\(g[i]\)为\(i\)出发的最长路,二者可以拓扑序后\(dp\)求得 那么一条边\((u,v ...
随机推荐
- 分别用C/C++ 和 C#实现简单的观察者模式
网上找了很多关于观察者模式的代码例子和文章,都写的比较复杂,我个人还是喜欢从易到难,今天自己参考网上资料,也写了一个简单观察者模式的例子,简单的复习了一下Observer 模式,Observer 模式 ...
- ORA-06512 问题解决
SQL> select * from dba_role_privs where grantee='SUK'; GRANTEE GRANTED_ROLE ADMIN_OPTION DEFA ...
- UITableView中cell点击的绚丽动画效果
UITableView中cell点击的绚丽动画效果 本人视频教程系类 iOS中CALayer的使用 效果图: 源码: YouXianMingCell.h 与 YouXianMingCell.m / ...
- mysql的表和约束操作
在创建表是默认为加上数据引擎和字符集,如创建一个student表,代码如下: create table students(id int unsigned zerofill auto_increment ...
- xdebug安装及使用小结
最近安装了一下xedug,并且学习了一下如何使用.安装xdebug的初衷是为了深入研究一下PHP的垃圾回收机制. Xdebug是一个开放源代码的PHP程序调试器(即一个Debug工具),可以用来跟踪, ...
- SGU---107 水题
题目链接: http://codeforces.com/problemsets/acmsguru/problem/99999/107 题目大意: 求n位数有多少个的平方末尾是987654321 思路: ...
- Golang - 数据库操作
1. 下载安装包 go get github.com/Go-SQL-Driver/MySQL go install github.com/Go-SQL-Driver/MySQL 2. 连接池 This ...
- 20155314 2016-2017-2 《Java程序设计》第4周学习总结
20155314 2016-2017-2 <Java程序设计>第4周学习总结 教材学习内容总结 理解封装.继承.多态的关系 理解抽象类与接口的区别 掌握S.O.L.I.D原则 了解模式和设 ...
- python 位置参数和关键字参数 *args **kwargs
#!/usr/bin/env pythondef foo(*args,**kwargs): print('args: {0}'.format(args)) print('kwargs {0}'.for ...
- Apache Shiro(一)-登录认证和权限管理初识
What is Apache Shiro? Apache Shiro是一个功能强大.灵活的,开源的安全框架.它可以干净利落地处理身份验证.授权.企业会话管理和加密. Apache Shiro的首要目标 ...