BZOJ3832: [Poi2014]Rally(拓扑排序 堆)
题意
Sol
最直观的思路是求出删除每个点后的最长路,我们考虑这玩意儿怎么求
设\(f[i]\)表示以\(i\)结尾的最长路长度,\(g[i]\)表示以\(i\)开始的最长路长度
根据DAG的性质,显然我们删除一个点后,整个集合会被分成两部分:拓扑序小于/大于当前点
那么此时的最长路一定可以通过计算连接着两个集合的边\((u, v)\)的\(f(u) + f(v) +1\)得到
这样的话我们可以直接维护边集,在统计每个点的答案的时候首先删掉入边的贡献统计答案,统计完后再加入出边的贡献
显然线段树可以维护,其实堆也可以维护,具体见代码(抄袭自yyb大佬)
#include<bits/stdc++.h>
#define chmax(x, y) (x = (x > y ? x : y))
#define chmin(x, y) (x = (x < y ? x : y))
using namespace std;
const int MAXN = 1e6 + 10, INF = 1e9 + 10;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, M, a1 = INF, a2;
class MyPriorityQueue {
public:
priority_queue<int> q1, q2;
void push(int x) {
q1.push(x);
}
int pop(int x) {
q2.push(x);
}
bool empty() {
while(!q2.empty() && (q1.top() == q2.top())) q1.pop(), q2.pop();
return q1.size() == 0;
}
int top() {
return empty() ? INF : q1.top();
}
};
MyPriorityQueue Q;
struct Graph {
vector<int> v[MAXN];
int f[MAXN], inder[MAXN], id[MAXN], tot;
Graph() {
tot = 0;
}
void AddEdge(int x, int y) {
v[x].push_back(y); inder[y]++;
}
void Topsort() {
queue<int> q;
for(int i = 1; i <= N; i++) if(!inder[i]) q.push(i);
while(!q.empty()) {
int p = q.front(); q.pop(); id[++tot] = p;
for(int i = 0; i < v[p].size(); i++) {
int to = v[p][i]; chmax(f[to], f[p] + 1);
if(!(--inder[to])) q.push(to);
}
}
}
};
Graph Gs, Gt;
int main() {
N = read(); M = read();
for(int i = 1; i <= M; i++) {
int x = read(), y = read();
Gs.AddEdge(x, y); Gt.AddEdge(y, x);
}
Gs.Topsort(); Gt.Topsort();
for(int i = 1; i <= N; i++) Q.push(Gt.f[i]);
for(int t = 1; t <= N; t++) {
int x = Gs.id[t]; Q.pop(Gt.f[x]);
for(int i = 0; i < Gt.v[x].size(); i++) {
int to = Gt.v[x][i];
Q.pop(Gs.f[to] + Gt.f[x] + 1);
}
int now = Q.top(); Q.push(Gs.f[x]);
if(now < a1) a1 = now, a2 = x;
for(int i = 0; i < Gs.v[x].size(); i++) {
int to = Gs.v[x][i];
Q.push(Gs.f[x] + Gt.f[to] + 1);
}
}
printf("%d %d\n", a2, a1);
return 0;
}
BZOJ3832: [Poi2014]Rally(拓扑排序 堆)的更多相关文章
- 【bzoj4010】[HNOI2015]菜肴制作 拓扑排序+堆
题目描述 给你一张有向图,问:编号-位置序(即每个编号的位置对应的序列)最小(例如1优先出现在前面,1位置相同的2优先出现在前面,以此类推)的拓扑序是什么? 输入 第一行是一个正整数D,表示数据组数. ...
- BZOJ3832[Poi2014]Rally——权值线段树+拓扑排序
题目描述 An annual bicycle rally will soon begin in Byteburg. The bikers of Byteburg are natural long di ...
- 【BZOJ-3832】Rally 拓扑序 + 线段树 (神思路题!)
3832: [Poi2014]Rally Time Limit: 20 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 168 Solved: ...
- [AGC010E] Rearranging [拓扑排序+堆]
题面 传送门 思路 首先,一个显然的结论是:Alice调整过后的序列中任意两个不互质的数的相对顺序无法改变 那么我们可以以这个性质为突破口 我们在两个不互质的权值的点之间连一条边(没错这是个图论题!! ...
- BZOJ3832 [Poi2014]Rally 【拓扑序 + 堆】
题目链接 BZOJ3832 题解 神思路orz,根本不会做 设\(f[i]\)为到\(i\)的最长路,\(g[i]\)为\(i\)出发的最长路,二者可以拓扑序后\(dp\)求得 那么一条边\((u,v ...
- BZOJ4010[HNOI2015]菜肴制作——拓扑排序+堆
题目描述 知名美食家小 A被邀请至ATM 大酒店,为其品评菜肴. ATM 酒店为小 A 准备了 N 道菜肴,酒店按照为菜肴预估的质量从高到低给予 1到N的顺序编号,预估质量最高的菜肴编号为1.由于菜肴 ...
- 并不对劲的bzoj3832: [Poi2014]Rally
传送门-> 这题的原理看上去很神奇. 称拓扑图中入度为0的点为“起点”,出度为0的点为“终点”. 因为“起点”和“终点”可能有很多个,算起来会很麻烦,所以新建“超级起点”S,向所有点连边,“超级 ...
- BZOJ3832 : [Poi2014]Rally
f[0][i]为i出发的最长路,f[1][i]为到i的最长路 新建源汇S,T,S向每个点连边,每个点向T连边 将所有点划分为两个集合S与T,一开始S中只有S,其它点都在T中 用一棵线段树维护所有连接属 ...
- bzoj 2535: [Noi2010]Plane 航空管制2【拓扑排序+堆】
有个容易混的概念就是第一问的答案不是k[i]字典序最小即可,是要求k[i]大的尽量靠后,因为这里前面选的时候是对后面有影响的(比如两条链a->b c->d,ka=4,kb=2,kc=3,k ...
随机推荐
- ActiveRecord::Fixture::FormatError: ActiveRecord::Fixture::FormatError
环境:window 7+ruby2.33+rails5.0.. 该提示的意思是固件格式错误: 但是又没有提示是哪一行 非常蛋疼,我照成的原因居然是没有对齐,请看:(下面的activated_at没有和 ...
- C#设计模式系列目录
http://www.cnblogs.com/libingql/archive/2012/04/16/2451608.html 抽空,学习,加强!
- 解析ASP.NET Mvc开发之查询数据实例 分类: ASP.NET 2014-01-02 01:27 5788人阅读 评论(3) 收藏
目录: 1)从明源动力到创新工场这一路走来 2)解析ASP.NET WebForm和Mvc开发的区别 ----------------------------------------------- ...
- APACHE 禁止通过IP直接访问
若是开通了虚拟主机,则需要在httpd-vhosts.conf中修改配置如下:若没有开通虚拟主机,则可以直接在httpd.conf文件最后面,加入以下代码: NameVirtualHost XXX.X ...
- IDEA Community(社区版)再谈之无奈之下还是去安装旗舰版
不多说,直接上干货! 前言 相信很多人,跟我一样,一开始,接触spark,肯定会首选IntelliJ IDEA的社区版Community. IntelliJ IDEA号称当前Java开发效率最高的ID ...
- Cloudera Manager安装之利用parcels方式安装3或4节点集群(包含最新稳定版本或指定版本的安装)(添加服务)(CentOS6.5)(五)
参考博客 Cloudera Manager安装之利用parcels方式安装单节点集群 Cloudera Manager安装之Cloudera Manager 5.3.X安装(三)(tar方式.rpm ...
- tomcat启动(Ⅶ)请求处理--Processor.process(SocketWrapper<S> socketWrapper)
tomcat启动(六)Catalina分析-StandardServer.start() 上一篇分析到:Http11NioProcessor.process(SocketWrapper<S> ...
- centos7-默认启动方式改变
在图形界面使用 ctrl+alt+F2切换到dos界面 dos界面 ctrl+alt+F2切换回图形界面 在命令上 输入 init 3 命令 切换到dos界面 输入 init 5命令 切换到图形界面 ...
- 为镜像添加SSH服务
操作Docker容器介绍了一些进入容器的办法,比如attach.exec等命令,但是这些命令都无法解决远程管理容器的问题.因此,当需要远程登录到容器内进行一些操作的时候,就需要SSH的支持了. 如何自 ...
- C#的进度条透明的情况(穿透问题)
如图: 很明显,可以看到透过进度条的框框可以看到下面的软件界面, 之前出现这种情况是因为pictureBox和panel层级之间的关系造成的, 没想到这次的原因居然不是这样,而是因为少了backCol ...