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 ...
随机推荐
- day 51 随机验证码, 验证登陆 ,以及 装饰器在函数中的应用
前端很好的session 的例子 (随机验证码登陆) https://github.com/Endless-Clould/qianduan 参考: 验证码登录 https://www.cnblogs. ...
- 【BZOJ2127】happiness 最小割
题目大意:有一个$n\times m$的矩阵,矩阵的每个位置上有一个同学,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦 ...
- WebDriverAPI(7)
查看页面元素的属性 测试网址 http://www.baidu.com Java语言版本API实例 @Test public void getWebElementAttribute() { dri ...
- HBase Cli相关操作
修改HBase表结构之前首先需要disable表,然后进行更改相关表结构信息,最后enable表,如下 1. 动态添加一个或多个列簇 hbase(main):034:0> describe 'H ...
- Java之IO(十)Reader和Writer
转载请注明源出处:http://www.cnblogs.com/lighten/p/7071733.html 1.前言 之前的章节已经将Java8的io包中的字节流介绍完毕了.本章开始介绍Java的I ...
- python中如何使输出不换行
1.在python 2.x版本中,使用“,”(不含双引号)可使输出不换行,例如 2.python 3.x版本输出不换行格式如下 print(x, end="") end=&q ...
- Java的Signature签名转换成.Net
Java: Signature sig = Signature.getInstance("SHA1withRSA"); sig.initSign(rsaPrivateKey); s ...
- Android 开发工具类 27_多线程下载大文件
多线程下载大文件时序图 FileDownloader.java package com.wangjialin.internet.service.downloader; import java.io.F ...
- [转] 用协议分析工具学习TCP/IP
一.前言 目前,网络的速度发展非常快,学习网络的人也越来越多,稍有网络常识的人都知道TCP/IP协议是网络的基础,是Internet的语言,可以说没有TCP/IP协议就没有互联网的今天.目前号称搞网的 ...
- js验证整数,浮点数
//验证数字(整数.浮点数都可以通过) function isfloat(oNum){ if(!oNum) return false; var strP=/^\d+(\.\d+)?$/; if(!st ...