Luogu 3627 [APIO2009]抢掠计划
不爽。
为什么tarjan能爆栈啊
十分显然的缩点,给缩点之后的点连上权值为后一个点集权值的有向边,然后spfa跑最长路。
注意一开始$dis_{st}$应该等于$st$这个集合的权值。
时间复杂度$O(能过)$。
非递归版的tarjan可以学习一下。
Code:
#include <cstdio>
#include <cstring>
#include <queue>
#include <stack>
using namespace std; const int N = 8e5 + ;
const int inf = 0x3f3f3f3f; int n, m, st, edNum, dfsc = , dfn[N], low[N], bel[N];
int tot = , head[N], scc = , a[N], val[N], dis[N];
int top = , sta[N], inx[N << ], iny[N << ];
bool vis[N], isEnd[N], sccEnd[N];
stack <int> S; struct Edge {
int to, nxt, val;
} e[N << ]; inline void add(int from, int to, int v = ) {
e[++tot].to = to;
e[tot].val = v;
e[tot].nxt = head[from];
head[from] = tot;
} inline void read(int &X) {
X = ;
char ch = ;
int op = ;
for(; ch > ''|| ch < ''; ch = getchar())
if(ch == '-') op = -;
for(; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} inline int min(int x, int y) {
return x > y ? y : x;
} inline void chkMax(int &x, int y) {
if(y > x) x = y;
} /*void tarjan(int x) {
dfn[x] = low[x] = ++dfsc;
sta[++top] = x, vis[x] = 1;
for(int i = head[x]; i; i = e[i].nxt) {
int y = e[i].to;
if(!dfn[y]) tarjan(y), low[x] = min(low[x], low[y]);
else if(vis[y]) low[x] = min(low[x], dfn[y]);
} if(low[x] == dfn[x]) {
++scc;
for(; sta[top + 1] != x; top--) {
sccEnd[scc] |= isEnd[sta[top]];
bel[sta[top]] = scc;
val[scc] += a[sta[top]];
vis[sta[top]] = 0;
}
}
} */ void tarjan(int fir) {
low[fir] = dfn[fir] = ++dfsc;
sta[++top] = fir, vis[fir] = ;
S.push(fir);
for(; !S.empty(); ) {
int x = S.top();
for(int i = head[x]; i; i = e[i].nxt) {
int y = e[i].to;
if(!dfn[y]) {
dfn[y] = low[y] = ++dfsc;
sta[++top] = y, vis[y] = ;
S.push(y);
break;
}
} if(x == S.top()) {
for(int i = head[x]; i; i = e[i].nxt) {
int y = e[i].to;
if(dfn[y] > dfn[x]) low[x] = min(low[x], low[y]);
else if(vis[y]) low[x] = min(low[x], dfn[y]);
} if(low[x] == dfn[x]) {
++scc;
for(; sta[top + ] != x; top--) {
sccEnd[scc] |= isEnd[sta[top]];
bel[sta[top]] = scc;
val[scc] += a[sta[top]];
vis[sta[top]] = ;
}
} S.pop();
}
}
} queue <int> Q;
void spfa() {
memset(dis, 0x3f, sizeof(dis)); dis[st] = -val[st];
Q.push(st); vis[st] = ;
for(; !Q.empty(); ) {
int x = Q.front(); Q.pop();
vis[x] = ;
for(int i = head[x]; i; i = e[i].nxt) {
int y = e[i].to;
if(dis[y] > dis[x] + e[i].val) {
dis[y] = dis[x] + e[i].val;
if(!vis[y]) Q.push(y), vis[y] = ;
}
}
}
} int main() {
read(n), read(m);
for(int x, y, i = ; i <= m; i++) {
read(x), read(y);
inx[i] = x, iny[i] = y;
add(x, y);
}
for(int i = ; i <= n; i++) read(a[i]);
read(st), read(edNum);
for(int x, i = ; i <= edNum; i++) read(x), isEnd[x] = ; for(int i = ; i <= n; i++)
if(!dfn[i]) tarjan(i); /* for(int i = 1; i <= n; i++)
printf("%d ", bel[i]);
printf("\n");
for(int i = 1; i <= n; i++)
printf("%d ", val[i]);
printf("\n"); */ tot = ; memset(head, , sizeof(head));
for(int i = ; i <= m; i++) {
if(bel[inx[i]] == bel[iny[i]]) continue;
add(bel[inx[i]], bel[iny[i]], -val[bel[iny[i]]]);
} st = bel[st];
spfa(); int ans = ;
for(int i = ; i <= scc; i++)
if(sccEnd[i] && dis[i] != inf) chkMax(ans, -dis[i]);
printf("%d\n", ans);
return ;
}
Luogu 3627 [APIO2009]抢掠计划的更多相关文章
- 【luogu P3627 [APIO2009]抢掠计划】 题解
题目链接:https://www.luogu.org/problemnew/show/P3627 把点权转化到边权上去. #include <stack> #include <que ...
- 洛谷3627 [APIO2009]抢掠计划
题目描述 输入格式: 第一行包含两个整数 N.M.N 表示路口的个数,M 表示道路条数.接下来 M 行,每行两个整数,这两个整数都在 1 到 N 之间,第 i+1 行的两个整数表示第 i 条道路的起点 ...
- 题解 P3627 【[APIO2009]抢掠计划】
咕了四个小时整整一晚上 P3627 [APIO2009] 抢掠计划(https://www.luogu.org/problemnew/show/P3627) 不难看出答案即为该有向图的最长链长度(允许 ...
- P3627 [APIO2009]抢掠计划
P3627 [APIO2009]抢掠计划 Tarjan缩点+最短(最长)路 显然的缩点...... 在缩点时,顺便维护每个强连通分量的总权值 缩完点按照惯例建个新图 然后跑一遍spfa最长路,枚举每个 ...
- APIO2009 抢掠计划 Tarjan DAG-DP
APIO2009 抢掠计划 Tarjan spfa/DAG-DP 题面 一道\(Tarjan\)缩点水题.因为可以反复经过节点,所以把一个联通快中的所有路口看做一个整体,缩点后直接跑\(spfa\)或 ...
- [APIO2009]抢掠计划(Tarjan,SPFA)
[APIO2009]抢掠计划 题目描述 Siruseri 城中的道路都是单向的.不同的道路由路口连接.按照法律的规定, 在每个路口都设立了一个 Siruseri 银行的 ATM 取款机.令人奇怪的是, ...
- 【洛谷P3627】[APIO2009]抢掠计划
抢掠计划 题目链接 比较水的缩点模板题,Tarjan缩点,重新建图,记录联通块的钱数.是否有酒吧 DAG上记忆化搜索即可 #include<iostream> #include<cs ...
- 洛谷 P3627 [APIO2009]抢掠计划 Tarjan缩点+Spfa求最长路
题目地址:https://www.luogu.com.cn/problem/P3627 第一次寒假训练的结测题,思路本身不难,但对于我这个码力蒟蒻来说实现难度不小-考试时肛了将近两个半小时才刚肛出来. ...
- [APIO2009]抢掠计划
题面: Description Siruseri城中的道路都是单向的.不同的道路由路口连接.按照法律的规定,在每个路口都设立了一个Siruseri银行的ATM取款机.令人奇怪的是,Siruseri的酒 ...
随机推荐
- 剑指offer--9.字符串的排列
next_permutation(),还是那个feel ------------------------------------------------------------------------ ...
- ZOJ2314 Reactor Cooling(有上下界的网络流)
The terrorist group leaded by a well known international terrorist Ben Bladen is buliding a nuclear ...
- Java 参数的和
public class CommandParamter { public static void main(String[] args) { // TODO Auto-generated metho ...
- 洛谷 P3904 三只小猪
题目背景 你听说过三只小猪的故事吗?这是一个经典的故事.很久很久以前,有三只小猪.第一只小猪用稻草建的房子,第二个小猪用木棍建的房子,第三个小猪则使用砖做为材料.一只大灰狼想吃掉它们并吹倒了稻草和木棍 ...
- Redis 分布式锁 - 分布式锁的正确实现方式
前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁.虽然网上已经有各种介 ...
- git revert reset
git revert是用一次新的commit来回滚之前的commit,git reset是直接删除指定的commit. git reset 是把HEAD向后移动了一下,而git revert是HEAD ...
- 机器学习:集成学习(Ada Boosting 和 Gradient Boosting)
一.集成学习的思路 共 3 种思路: Bagging:独立的集成多个模型,每个模型有一定的差异,最终综合有差异的模型的结果,获得学习的最终的结果: Boosting(增强集成学习):集成多个模型,每个 ...
- Angular常犯的错误
ng-app="name名称" name名称 == 一定要写对 其次 angular.min导入一定要正确,一定要导入正确的angular.min的库 再次js中要写自调用 (f ...
- MyCAT 1.6 安装部署
1 mycat 安装部署 1 下载解压Mycat-server-1.6-RELEASE-20161010173036-linux.tar.gz 到/usr/local/mycat 2 下载解压jdk- ...
- 侯捷STL学习(六)--深入list && Iterator traits
第十三,四节 深度探索list(上,下) list Gnu2.9源代码实现 注意node代码和图示的位置 实现前闭后开,增加一个空白节点 用的分配器alloc Iterator智能指针,需要知道结点n ...