思路 : 这道题是一道Tarjan + 最长路的题。首先,我们用Tarjan把每个强连通分量缩成一个点,并记录那个强连通分量的点权和(因为当那个人走进一个强连通分量后那个强连通分量中的所有money都会被他拿走(绕一圈不就完了?)),然后我们化点权为边权,再以起点所在的强连通分量跑最长路,最后就能计算出从起点所在的强连通分量到任意一个终点所在的强连通分量的最长距离了(最大money值),输出的是取从起点所在的强连通分量到任意一个终点所在的强连通分量的最大值。


细节问题 :

  • 关于如何把点权转化为边权:很简单,设u -> k有一条路,q[i]表示点i的权值,边的权值就是q[u],最后我们只需把q[最后一个点的权值(终点)]加上就好了。
  • 关于如何建边:只需把不在同一个强连通分量中的可以连接的边连起来就好了(注意:是连两个点所在的的强连通分量)。
  • 关于如何跑最长路:我们只学过最短路,但没学过该如何跑最长路,所以我们化未知变为已知,把最长路化为最短路。你们仔细想一想,如果我们把边权建为负的,是不是就可以跑最短路了?最后再把距离 * -1 不就完了?

code:

 #include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
stack < int > pru;
int n, m, p, head[], q[], col[], color, dfn[], low[], s, e[], sum[], z, num, vis[], dis[], ans;//变量太多懒得解释,意会一下吧。。。
struct node//存边
{
int next, to, val;
}stu[];
queue < node > G;//用于临时存放边
inline void add(int x, int y, int z)
{
stu[++num].next = head[x];
stu[num].to = y;
stu[num].val = z;
head[x] = num;
return;
}
inline void tarjan(int u)//Tarjan算法,这里用于缩点
{
dfn[u] = low[u] = ++z;
vis[u] = ;
pru.push(u);
for(register int i = head[u]; i; i = stu[i].next)
{
int k = stu[i].to;
if(!vis[k])
{
tarjan(k);
low[u] = min(low[u], low[k]);
}
else if(!col[k])
{
low[u] = min(low[u], dfn[k]);
}
}
if(dfn[u] == low[u])
{
col[u] = ++color;
sum[color] += q[u];//权值和
while(pru.top() != u)
{
col[pru.top()] = color;
sum[color] += q[pru.top()];//权值和
pru.pop();
}
pru.pop();
}
return;
}
inline void spfa(int s)//求最短路模板SPFA
{
queue < int > pru;
memset(vis, , sizeof(vis));
memset(dis, INF, sizeof(dis));
pru.push(s);
dis[s] = ;
vis[s] = ;
while(!pru.empty())
{
int u = pru.front();
pru.pop();
vis[u] = ;
for(register int i = head[u]; i; i = stu[i].next)
{
int k = stu[i].to;
if(dis[k] > dis[u] + stu[i].val)
{
dis[k] = dis[u] + stu[i].val;
if(!vis[k])
{
vis[k] = ;
pru.push(k);
}
}
}
}
return;
}
inline void init()//初始化
{
memset(head, , sizeof(head));
for(register int i = ; i <= ; ++i)
{
stu[i].next = ;
stu[i].to = ;
stu[i].val = ;
}
num = ;
return;
}
inline void add_edge()
{
for(register int u = ; u <= n; ++u)
{
for(register int i = head[u]; i; i = stu[i].next)
{
int k = stu[i].to;
if(col[k] != col[u])//不在一个强连通分量中才建边
{
//需要临时先放到G里,因为如果还没有把那些一大堆东西初始化就又建边,会.......
G.push(node{col[u], col[k], -sum[col[u]]});//要建负边权(这样可以把最长路转化为最短路)
}
}
}
init();//初始化
while(!G.empty())//初始化完再存边
{
node p = G.front();
add(p.next, p.to, p.val);//建边
G.pop();
}
return;
}
signed main()
{
scanf("%d %d", &n, &m);
for(register int i = , x, y; i <= m; ++i)
{
scanf("%d %d", &x, &y);
add(x, y, );
}
for(register int i = ; i <= n; ++i)
{
scanf("%d", &q[i]);
}
scanf("%d %d", &s, &p);
for(register int i = ; i <= p; ++i)
{
scanf("%d", &e[i]);
}
for(register int i = ; i <= n; ++i)
{
if(!vis[i])
{
tarjan(i);
}
}
add_edge();//建边
spfa(col[s]);//从起点所在的强连通分量中开始
for(register int i = ; i <= p; ++i)
{
ans = max(ans, dis[col[e[i]]] * -/*别忘了把它变回正数*/ + sum[col[e[i]]]/*别加上终点所在的强联通分量的权值*/);
}
printf("%d", ans);
return ;
}

洛谷 P3627 【抢掠计划】的更多相关文章

  1. 【题解】洛谷P3627 [APIO2009]抢掠计划(缩点+SPFA)

    洛谷P3627:https://www.luogu.org/problemnew/show/P3627 思路 由于有强连通分量 所以我们可以想到先把整个图缩点 缩点完之后再建一次图 把点权改为边权 并 ...

  2. 洛谷 P1251 餐巾计划问题(线性规划网络优化)【费用流】

    (题外话:心塞...大部分时间都在debug,拆点忘记加N,总边数算错,数据类型标错,字母写错......) 题目链接:https://www.luogu.org/problemnew/show/P1 ...

  3. 洛谷 P2680 运输计划-二分+树上差分(边权覆盖)

    P2680 运输计划 题目背景 公元 20442044 年,人类进入了宇宙纪元. 题目描述 公元20442044 年,人类进入了宇宙纪元. L 国有 nn 个星球,还有 n-1n−1 条双向航道,每条 ...

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

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

  5. BZOJ4326或洛谷2680 运输计划

    BZOJ原题链接 洛谷原题链接 用\(LCA\)初始化出所有运输计划的原始时间,因为答案有单调性,所以二分答案,然后考虑检验答案. 很容易想到将所有超出当前二分的答案的运输计划所经过的路径标记,在这些 ...

  6. loj2734「JOISC 2016 Day 2」女装大佬 || 洛谷P3615 如厕计划

    loj2734 洛谷P3615 http://218.5.5.242:9021/problem/185 不会做... 题解(来自ditoly): 这一步更详细的解释(来自kkksc03): 还是从后面 ...

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

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

  8. 洛谷P3627[APOI2009] (讨厌的)抢掠计划

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

  9. 洛谷 P3627 [APIO2009](抢掠计划 缩点+spfa)

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

随机推荐

  1. rabbitMQ_routing(四)

    路由 本次我们将通过路由将信息发送到指定的队列中,将消息发送给指定的队列需要在转发器和队列之间建立一个routeKey 绑定 在以前的例子中,我们已经创建了绑定.你可能会记得如下代码: channel ...

  2. httpclient信任所有证书解决SSLException:Unrecognized SSL message,plaintext connection

    在使用 HttpClient 工具调用第三方 Http 接口时报错 javax.net.ssl.SSLException:Unrecognized SSL message,plaintext conn ...

  3. Spring WebClient vs. RestTemplate

    1. 简介 本教程中,我们将对比 Spring 的两种 Web 客户端实现 -- RestTemplate 和 Spring 5 中全新的 Reactive 替代方案 WebClient. 2. 阻塞 ...

  4. vue教程二 vue组件(1)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <script ...

  5. TCP加速机制是如何加速的?

    一.什么是TCP加速?   TCP加速就是在高时延链路提高吞吐量的一系列解决方案.   二.为什么需要对TCP进行加速?   1.传统的TCP拥塞控制算法并不适用于高时延.高误码的链路. 2.随着we ...

  6. Java编程基础阶段笔记 day06 二维数组

    二维数组 笔记Notes 二维数组 二维数组声明 二维数组静态初始化与二位初始化 二维数组元素赋值与获取 二维数组遍历 二维数组内存解析 打印杨辉三角 Arrays工具类 数组中常见的异常 二维数组 ...

  7. React Hooks 深入系列 —— 设计模式

    本文是 React Hooks 深入系列的后续.此篇详细介绍了 Hooks 相对 class 的优势所在, 并介绍了相关 api 的设计思想, 同时对 Hooks 如何对齐 class 的生命周期钩子 ...

  8. MySQL5.7运行CPU达百分之400处理方案

    用户在使用 MySQL 实例时,会遇到 CPU 使用率过高甚至达到 100% 的情况.本文将介绍造成该状况的常见原因以及解决方法,并通过 CPU 使用率为 100% 的典型场景,来分析引起该状况的原因 ...

  9. 用python实现九九乘法表输出-两种方法

    2019-08-05 思考过程:九九乘法表需要两层循环,暂且称之为内循环和外循环,因此需要写双层循环来实现. 循环有for和while两种方式. for循环的实现 for i in range(1,1 ...

  10. SDS模块

    早上花了一点时间读了下sds的相关源码,其实sds就是构造了两个字段用来记录len和free的状态,然后还有一个char[]用来记录字符串的值. 然后sds模块的函数都是在模拟str的操作. 比较,追 ...