不爽。

为什么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. shell_script_查询主机名、ip地址 、DNS地址

    #!/bin/bashhostnameip=`/sbin/ifconfig eth0|grep "inet addr:"|sed 's/Bcast.*$//'g |awk -F & ...

  2. hdoj-1106-排序(stringstream)

    题目链接 /* Name: Copyright: Author: Date: 2018/5/2 20:56:53 Description: */ #include <iostream> # ...

  3. CODE FESTIVAL 2017 qual A--C - Palindromic Matrix(模拟所有情况,注意细节)

    个人心得:其实本来这题是有规律的不过当时已经将整个模拟过程都构思出来了,就打算试试,将每个字符和总和用优先队列 装起来,然后枚举每个点,同时进行位置标志,此时需要多少个点的时候拿出最大的和出来,若不满 ...

  4. QAbstractSocket::connectToHost() called when already looking up or connecting/connected to

    tcpSocket_connect_HBJ->abort();//取消已有连接,重置套接字,tcpSocket_connect_HBJ是QTcpSocket类的对象 就不会报错了.

  5. Linux Matlab mex gcc 版本

    一般MATLAB的mex支持的gcc版本都比最新的gcc要低一些,所以一般要配置一下. 假设当前版本的gcc是4.8,matlab支持4.6,可以使用以下的方式解决(任选一种).(自己装好gcc-4. ...

  6. C#中获取Excel文件的第一个表名

    //    2.以数据库方式打开并输入数据//      此方式将xls文件所在目录看作数据库,其中的xls文件看作数据库表,表名即文件名(不加扩展名).//      函数importExcelTo ...

  7. JDK 8 - JVM 对类的初始化探讨

    在<深入理解 Java 虚拟机>(第二版,周志明著)中,作者介绍了 JVM 必须初始化类(或接口)的五种情况,但是是针对 JDK 7 而言的. 那么,在 JDK 8 中,这几种情况有没有变 ...

  8. 关于64位操作系统使用C#访问注册表失败的问题

    通过C#的注册表类 Registry.GetValue 进行访问时,其返回值一直为空.然后认真检查检查再检查了注册表路径,发现路径没有一点问题,不说废话,上代码: if (Registry.GetVa ...

  9. AngularJS核心特性(四大点)

    本人刚刚接触AngularJS,还不太熟悉,就说说我目前遇到的一些注意点吧. 1.调用外来文件script文件 AngularJS核心特性一  MVC MVC设计模式 html文件 <!DOCT ...

  10. MacOS配置Erlang开发环境

    Mac下安装Erlang brew 的安装: $ curl -LsSf http://github.com/mxcl/homebrew/tarball/master | sudo tar xvz -C ...