不爽。

为什么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]抢掠计划的更多相关文章

  1. 【luogu P3627 [APIO2009]抢掠计划】 题解

    题目链接:https://www.luogu.org/problemnew/show/P3627 把点权转化到边权上去. #include <stack> #include <que ...

  2. 洛谷3627 [APIO2009]抢掠计划

    题目描述 输入格式: 第一行包含两个整数 N.M.N 表示路口的个数,M 表示道路条数.接下来 M 行,每行两个整数,这两个整数都在 1 到 N 之间,第 i+1 行的两个整数表示第 i 条道路的起点 ...

  3. 题解 P3627 【[APIO2009]抢掠计划】

    咕了四个小时整整一晚上 P3627 [APIO2009] 抢掠计划(https://www.luogu.org/problemnew/show/P3627) 不难看出答案即为该有向图的最长链长度(允许 ...

  4. P3627 [APIO2009]抢掠计划

    P3627 [APIO2009]抢掠计划 Tarjan缩点+最短(最长)路 显然的缩点...... 在缩点时,顺便维护每个强连通分量的总权值 缩完点按照惯例建个新图 然后跑一遍spfa最长路,枚举每个 ...

  5. APIO2009 抢掠计划 Tarjan DAG-DP

    APIO2009 抢掠计划 Tarjan spfa/DAG-DP 题面 一道\(Tarjan\)缩点水题.因为可以反复经过节点,所以把一个联通快中的所有路口看做一个整体,缩点后直接跑\(spfa\)或 ...

  6. [APIO2009]抢掠计划(Tarjan,SPFA)

    [APIO2009]抢掠计划 题目描述 Siruseri 城中的道路都是单向的.不同的道路由路口连接.按照法律的规定, 在每个路口都设立了一个 Siruseri 银行的 ATM 取款机.令人奇怪的是, ...

  7. 【洛谷P3627】[APIO2009]抢掠计划

    抢掠计划 题目链接 比较水的缩点模板题,Tarjan缩点,重新建图,记录联通块的钱数.是否有酒吧 DAG上记忆化搜索即可 #include<iostream> #include<cs ...

  8. 洛谷 P3627 [APIO2009]抢掠计划 Tarjan缩点+Spfa求最长路

    题目地址:https://www.luogu.com.cn/problem/P3627 第一次寒假训练的结测题,思路本身不难,但对于我这个码力蒟蒻来说实现难度不小-考试时肛了将近两个半小时才刚肛出来. ...

  9. [APIO2009]抢掠计划

    题面: Description Siruseri城中的道路都是单向的.不同的道路由路口连接.按照法律的规定,在每个路口都设立了一个Siruseri银行的ATM取款机.令人奇怪的是,Siruseri的酒 ...

随机推荐

  1. poj2263 zoj1952 Heavy Cargo(floyd||spfa)

    这道题数据范围小,方法比较多.我用floyd和spfa分别写了一下,spfa明显有时间优势. 一个小技巧在于:把城市名称对应到数字序号,处理是用数字. 方法一:spfa #include<ios ...

  2. uva10815(set的应用)

    紫书例题,这道题的例程让我长了知识.以前没有用过cctype和stringstream相关的东西.很实用,值得学习. #include <cctype>的函数 c++中应该是#includ ...

  3. MySQL引擎各个引擎对比介绍

    1.什么是存储引擎? 存储引擎类似于录制的视频文件,可以转换成不同的格式,如MP4,avi等格式,而存储在我们的磁盘上也会存在于不同类型的文件系统中如:Windows里常见的NTFS,fat32等.存 ...

  4. [BZOJ5249][多省联测2018]IIIDX

    bzoj luogu sol 首先可以把依赖关系转成一个森林.自下而上维护出每个点的\(size\),表示这关解锁以后一共有多少关. 考虑没有重复数字的情况. 直接从小往大贪心把每个数赋给当前已解锁的 ...

  5. Leetcode Longest Uncommon Subsequence I

    原题链接在这里:https://leetcode.com/problems/longest-uncommon-subsequence-i/#/description 题目: Given a group ...

  6. LeetCode Perfect Number

    原题链接在这里:https://leetcode.com/problems/perfect-number/#/description 题目: We define the Perfect Number ...

  7. NSString *const 和 const NSString * 的区别

    1.变量存储的指针可变,变量存储的值不可变 //A modifiable pointer to a constant NSString (its value can't be modified) &q ...

  8. 使用Jsonp实现跨域请求

    来自百度百科的一段话: JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题.由于同源策略,一般来说位于 server1.exampl ...

  9. JavaScript函数的默认参数(default parameter)

    JavaScript函数的默认参数(default parameter) js函数参数的默认值都是undefined, ES5里,不支持直接在形参里写默认值.所以,要设置默认值,就要检测参数是否为un ...

  10. 单端IO标准

    单端标准 常用的单端IO标准是LVTTL和LVCMOS. 目前业界绝大部分FPGA/CPLD器件的LVCOMS的IO是由CMOS推挽(push-pull)驱动器构成的,这种结构是上面的PMOS管和下面 ...