题面

传送门

分析

由于一个点可以经过多次,显然每个环都会被走一遍。

考虑缩点,将每个强连通分量缩成一个点,点权为联通分量上的所有点之和

缩点后的图是一个有向无环图(DAG)

可拓扑排序,按照拓扑序进行DP

子状态:\(dp[i]\)表示以i结尾的路径的最大权值和

状态转移方程 \(dp[y]=max(dp[y],dp[x]+val[y]) ( (x,y) \in E)\)

最终的答案为max(dp[belong[u]]),其中u是酒吧编号,belong[u]表示酒吧所在的联通分量

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<stack>
#include<map>
#define maxn 500005
using namespace std;
struct edge{
int u;
int v;
edge(){ }
edge(int from,int to){
u=from;
v=to;
}
friend bool operator < (edge a,edge b){
if(a.u==b.u) return a.v<b.v;
else return a.u<b.u;
}
};
map<edge,int>used;
int n,m,st,p;
vector<int>G[maxn];
vector<int>D[maxn];
int money[maxn];
int tim=0;
int cnt=0;
int dfn[maxn];
int low[maxn];
int ins[maxn];
int belong[maxn];
long long dp[maxn],val[maxn];
stack<int>s;
void tarjan(int x){
s.push(x);
ins[x]=1;
dfn[x]=low[x]=++tim;
int t=G[x].size();
for(int i=0;i<t;i++){
int y=G[x][i];
if(!dfn[y]){
tarjan(y);
low[x]=min(low[x],low[y]);
}else if(ins[y]){
low[x]=min(low[x],dfn[y]);
}
}
if(low[x]==dfn[x]){
cnt++;
int y;
do{
y=s.top();
s.pop();
ins[y]=0;
val[cnt]+=money[y];
belong[y]=cnt;
}while(x!=y);
}
} int in[maxn];
int out[maxn];
void graph_to_dag(){
for(int i=1;i<=n;i++){
if(!dfn[i]) tarjan(i);
}
for(int i=1;i<=n;i++){
int t=G[i].size();
for(int j=0;j<t;j++){
int k=G[i][j];
if(belong[i]!=belong[k]){
if(used.count(edge(belong[i],belong[k]))) continue;
used[edge(belong[i],belong[k])]=1;
D[belong[i]].push_back(belong[k]);
in[belong[k]]++;
}
}
}
} int is_ok[maxn];
void topo_sort(int s){
queue<int>q;
is_ok[s]=1;
for(int i=1;i<=cnt;i++){
if(in[i]==0){
q.push(i);
}
}
dp[s]=val[s];
while(!q.empty()){
int x=q.front();
q.pop();
int t=D[x].size();
for(int i=0;i<t;i++){
int y=D[x][i];
in[y]--;
if(is_ok[x]){
dp[y]=max(dp[y],dp[x]+val[y]);
is_ok[y]=1;
}
if(in[y]==0) q.push(y);
}
}
} int main(){
int u,v;
scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%d %d",&u,&v);
G[u].push_back(v);
}
for(int i=1;i<=n;i++){
scanf("%d",&money[i]);
}
graph_to_dag();
scanf("%d %d",&st,&p);
topo_sort(belong[st]);
long long ans=0;
for(int i=1;i<=p;i++){
scanf("%d",&u);
ans=max(ans,dp[belong[u]]);
}
printf("%lld\n",ans);
}

BZOJ 1179 (Tarjan缩点+DP)的更多相关文章

  1. 硬币问题 tarjan缩点+DP 莫涛

    2013-09-15 20:04 题目描述 有这样一个游戏,桌面上摆了N枚硬币,分别标号1-N,每枚硬币有一个分数C[i]与一个后继硬币T[i].作为游戏参与者的你,可以购买一个名为mlj的小机器人, ...

  2. 【Codeforces】894E.Ralph and Mushrooms Tarjan缩点+DP

    题意 给定$n$个点$m$条边有向图及边权$w$,第$i$次经过一条边边权为$w-1-2.-..-i$,$w\ge 0$给定起点$s$问从起点出发最多能够得到权和,某条边可重复经过 有向图能够重复经过 ...

  3. Libre OJ 2255 (线段树优化建图+Tarjan缩点+DP)

    题面 传送门 分析 主体思路:若x能引爆y,从x向y连一条有向边,最后的答案就是从x出发能够到达的点的个数 首先我们发现一个炸弹可以波及到的范围一定是坐标轴上的一段连续区间 我们可以用二分查找求出炸弹 ...

  4. NOIP2009最优贸易[spfa变形|tarjan 缩点 DP]

    题目描述 C 国有 n 个大城市和 m 条道路,每条道路连接这 n 个城市中的某两个城市.任意两个 城市之间最多只有一条道路直接相连.这 m 条道路中有一部分为单向通行的道路,一部分 为双向通行的道路 ...

  5. bzoj 1179 tarjan+spfa

    首先我们可以将这个图缩成DAG,那么问题中的路线就可以简化为DAG中的一条链,那么我们直接做一遍spfa就好了. 反思:开始写的bfs,结果bfs的时候没有更新最大值,而是直接赋的值,后来发现不能写b ...

  6. BZOJ 1179 抢掠计划atm (缩点+有向无环图DP)

    手动博客搬家: 本文发表于20170716 10:58:18, 原地址https://blog.csdn.net/suncongbo/article/details/81061601 https:// ...

  7. 【BZOJ-1924】所驼门王的宝藏 Tarjan缩点(+拓扑排序) + 拓扑图DP

    1924: [Sdoi2010]所驼门王的宝藏 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 787  Solved: 318[Submit][Stat ...

  8. BZOJ 1051 受欢迎的牛(Tarjan缩点)

    1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 4573  Solved: 2428 [Submit][S ...

  9. BZOJ 1179: [Apio2009]Atm( tarjan + 最短路 )

    对于一个强连通分量, 一定是整个走或者不走, 所以tarjan缩点然后跑dijkstra. ------------------------------------------------------ ...

随机推荐

  1. PKUSC2019颓废记

    Day -x \(THU\):"想过初审?gck" 我:"你说gck,那就gck⑧" 于是就来\(PKU\)碰碰运气了 Day 0 为了赶高铁起的很早. 颓了一 ...

  2. 【03】Python 文件读写 JSON

    1 打开文件 文件操作步骤: 1.打开文件获取文件的句柄,句柄就理解为这个文件 2.通过文件句柄操作文件 3.关闭文件. 1.1 打开方法 f = open('xxx.txt') #需f.close( ...

  3. hihocoder 1582 : Territorial Dispute (计算几何)(2017 北京网络赛E)

    题目链接 题意:给出n个点.用两种颜色来给每个点染色.问能否存在一种染色方式,使不同颜色的点不能被划分到一条直线的两侧. 题解:求个凸包(其实只考虑四个点就行.但因为有板子,所以感觉这样写更休闲一些. ...

  4. JavaScript赋值运算符和关系运算符

    赋值运算符:用以给变量进行赋值 最常见的赋值运算符就是等号(=),将右侧的值赋给左侧的变量(表达式x=y表示将y赋值给x) x += y // 等同于 x = x + y 还有其他更多的复合赋值运算 ...

  5. 最短路(模板)【CodeChef CLIQUED,洛谷P3371】

    自TG滚粗后咕咕咕了这么久,最近重新开始学OI,也会慢慢开始更博了.... 最短路算法经典的就是SPFA(Bellman-Ford),Dijkstra,Floyd: 本期先讲两个经典的单源最短路算法: ...

  6. es之java操作插入文档

    4方式: . 使用json字符串直接创建 . 使用Map集合 . 使用第三方库来序列化 createDocumentBySerialize . 使用内置的帮助器XContentFactory.json ...

  7. UVALive 6858 Frame (模拟)

    Frame 题目链接: http://acm.hust.edu.cn/vjudge/contest/130303#problem/D Description http://7xjob4.com1.z0 ...

  8. [CERC2016]:凸轮廓线Convex Contour(模拟+数学)

    题目描述 一些几何图形整齐地在一个网格图上从左往右排成一列.它们占据了连续的一段横行,每个位置恰好一个几何图形.每个图形是以下的三种之一:$1.$一个恰好充满单个格子的正方形.$2.$一个内切于单个格 ...

  9. [CSP-S模拟测试]:big(Trie树+贪心)

    题目描述 你需要在$[0,2^n)$中选一个整数$x$,接着把$x$依次异或$m$个整数$a_1~a_m$.在你选出$x$后,你的对手需要选择恰好一个时刻(刚选完数时.异或一些数后或是最后),将$x$ ...

  10. 基于自定义的动态数组实现一个栈(Java语言)

    关于动态数组,参见我的上一篇关于动态数组的博文https://www.cnblogs.com/inu6/p/11717129.html 1.什么是栈? (1)只能从一端添加元素,也只能从一端取出元素, ...