题面

传送门

分析

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

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

缩点后的图是一个有向无环图(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. unkown类型

    1,任何类型的值都可以赋给 unkown类型 2. 如果没有类型断言或基于控制流的类型细化时 unknown 不可以赋值给其它类型,此时它只能赋值给 unknown 和 any 类型 3. 如果没有类 ...

  2. vue开发知识点总结

    一.vue介绍 Vue.js 是一套构建用户界面(UI)的渐进式JavaScript框架,是一个轻量级MVVM(model-view-viewModel)框架. 二.数据绑定 最常用的方式:Musta ...

  3. expect实现远程主机自动执行命令脚本

    2014年第一个脚本,哈哈!!! expect实现远程主机自动执行命令脚本: #!/usr/bin/expect -- if { [llength $argv] < 4 } { puts &qu ...

  4. 043:Django使用原生SQL语句操作数据库

    Django使用原生SQL语句操作数据库 Django配置连接数据库: 在操作数据库之前,首先先要连接数据库.这里我们以配置 MySQL 为例来讲解. Django 连接数据库,不需要单独的创建一个连 ...

  5. Jion的应用

  6. 6411. 【NOIP2019模拟11.06】上网

    题目描述 Description Input Output 若无解,则输出"Impossible". 否则第一行输出"Possible",第二行输出 n 个正整 ...

  7. iOS 指定位置切圆角不生效问题

    如果是在VC中操作,需要在viewDidLayoutSubviews方法里 - (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; ...

  8. OC项目调用C++

    CPPHello.hpp #ifndef CPPHello_hpp #define CPPHello_hpp #include <stdio.h> class CPPHello { pub ...

  9. mysql 语句积累

    show tables; 显示表 DROP TABLE IF EXISTS emp;删除表

  10. Leetcode 4. Median of Two Sorted Arrays(中位数+二分答案+递归)

    4. Median of Two Sorted Arrays Hard There are two sorted arrays nums1 and nums2 of size m and n resp ...