[Luogu2656]采蘑菇
题目大意:
给你一个有向图,每条边有一个边权w以及恢复系数k,
你从s点出发乱走,经过某条边时会获得相应的收益w,而当第二次经过这条边时相应的收益为w*k下取整。
问你最大能获得的收益为多少?
思路:
缩点+DP。
首先跑一下Tarjan(只要从s开始跑,因为没跑到的地方肯定和答案没关系)。
对于每个强连通分量,我们算一下经过这个强联通分量能获得的总收益sum(就是拼命在这上面绕圈圈)。
把原图缩为一个DAG,然后就可以DP了。
设当前点为i,后继结点为j,边权为w,j的SCC的总收益为sum[j],转移方程为f[j]=max{f[i]+w+sum[j]}。
当然也只要从s开始DP即可。
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<vector>
#include<cstring>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return x;
}
const int N=,M=;
struct Edge {
int from,to,w;
double k;
int next;
};
Edge e[M];
int head[N];
inline void add_edge(const int &u,const int &v,const int &w,const double &k,const int &i) {
e[i]=(Edge){u,v,w,k,head[u]};
head[u]=i;
}
int s;
int dfn[N],low[N],scc[N],cnt,id,sum[N],in[N];
bool ins[N];
std::stack<int> stack;
void tarjan(const int &x) {
dfn[x]=low[x]=++cnt;
stack.push(x);
ins[x]=true;
for(int i=head[x];~i;i=e[i].next) {
const int &y=e[i].to;
if(!dfn[y]) {
tarjan(y);
low[x]=std::min(low[x],low[y]);
} else if(ins[y]) {
low[x]=std::min(low[x],dfn[y]);
}
}
if(dfn[x]==low[x]) {
id++;
int y=;
while(y!=x) {
y=stack.top();
stack.pop();
ins[y]=false;
scc[y]=id;
}
}
}
int ans,f[N];
std::queue<int> q;
inline void dp() {
q.push(scc[s]);
f[scc[s]]=sum[scc[s]];
while(!q.empty()) {
const int x=q.front();
q.pop();
ans=std::max(ans,f[x]);
for(register int i=head[x];~i;i=e[i].next) {
const int &y=e[i].to;
f[y]=std::max(f[y],f[x]+e[i].w+sum[y]);
if(!--in[y]) q.push(y);
}
}
}
int main() {
const int n=getint(),m=getint();
memset(head,-,sizeof head);
for(register int i=;i<m;i++) {
const int u=getint(),v=getint(),w=getint();
double k;
scanf("%lf",&k);
add_edge(u,v,w,k,i);
}
s=getint();
tarjan(s);
memset(head,-,sizeof head);
for(register int i=;i<m;i++) {
const int &u=e[i].from,&v=e[i].to;
if(!dfn[u]||!dfn[v]) continue;
if(scc[u]==scc[v]) {
const double &k=e[i].k;
int w=e[i].w;
while(w>) {
sum[scc[u]]+=w;
w=floor(w*k);
}
} else {
in[scc[v]]++;
add_edge(scc[u],scc[v],e[i].w,e[i].k,i);
}
}
dp();
printf("%d\n",ans);
return ;
}
[Luogu2656]采蘑菇的更多相关文章
- [Luogu 2656] 采蘑菇
Description 小胖和ZYR要去ESQMS森林采蘑菇. ESQMS森林间有N个小树丛,M条小径,每条小径都是单向的,连接两个小树丛,上面都有一定数量的蘑菇.小胖和ZYR经过某条小径一次,可以采 ...
- 【Foreign】采蘑菇 [点分治]
采蘑菇 Time Limit: 20 Sec Memory Limit: 256 MB Description Input Output Sample Input 5 1 2 3 2 3 1 2 1 ...
- 洛谷——P2656 采蘑菇
P2656 采蘑菇 题目描述 小胖和ZYR要去ESQMS森林采蘑菇. ESQMS森林间有N个小树丛,M条小径,每条小径都是单向的,连接两个小树丛,上面都有一定数量的蘑菇.小胖和ZYR经过某条小径一次, ...
- 洛谷—— P2656 采蘑菇
https://www.luogu.org/problem/show?pid=2656 题目描述 小胖和ZYR要去ESQMS森林采蘑菇. ESQMS森林间有N个小树丛,M条小径,每条小径都是单向的,连 ...
- 【细节题 离线 树状数组】luoguP4919 Marisa采蘑菇
歧义差评:但是和题意理解一样了之后细节依然处理了很久,说明还是水平不够…… 题目描述 Marisa来到了森林之中,看到了一排nn个五颜六色的蘑菇,编号从1-n1−n,这些蘑菇的颜色分别为col[1], ...
- F 采蘑菇的克拉莉丝
这是一道树链剖分的题目: 很容易想到,我们在树剖后,对于操作1,直接单点修改: 对于答案查询,我们直接的时候,我们假设查询的点是3,那么我们在查询的时候可分为两部分: 第一部分:查找出除3这颗子树以外 ...
- Luogu P2656 采蘑菇
尽管是缩点的习题,思路也是在看了题解后才明白的. 首先,每个强连通分量内的点都是一定互通的,也就是可以完全把这里面的边都跑满,摘掉所有能摘的蘑菇.那么,考虑给每一个强连通分量化为的新点一个点权,代表摘 ...
- [Luogu1119]采蘑菇
题目大意: 给你一个无向图,点i在时间t[i]之前是不存在的,有q组询问,问你时间为t时从x到y的最短路. 点的编号按出现的时间顺序给出,询问也按照时间顺序给出. 思路: Floyd. Floyd的本 ...
- Wannafly Camp 2020 Day 2F 采蘑菇的克拉莉丝 - 树链剖分
如果暴力维护,每次询问时需要对所有孩子做计算 考虑通过树剖来平衡修改与询问的时间,询问时计算重链和父树,轻链的贡献预先维护好,修改时则需要修改可能影响的轻链贡献,因为某个点到根的路径上轻重交替只有 \ ...
随机推荐
- 灵活使用ARM汇编的WEAK关键字
//=====================================================================//TITLE:// 灵活使用ARM汇编的WEAK关 ...
- sublime在搜索的时候排除js文件
代码审计的时候sublime是一个神器.所以.... Ctrl + Shift + F /home/i3ekr/Desktop/coding/phpcms,*.php 这样就可以直接搜索所有的php文 ...
- linux平台学x86汇编语言学习集合帖
linux平台学x86汇编语言学习集合帖 linux平台学x86汇编(一):https://blog.csdn.net/shallnet/article/details/45543237 linux平 ...
- $(document).ready 和 window.onload 的区别
1.相同点 两者都用于在网页加载完后执行相应代码块. 2.不同点 window.onload 在创建完 DOM 树后,所有外部资源(图片.Flash 动画等)加载完成,且整个页面在浏览器窗口中显示完毕 ...
- nginx源码分析--使用GDB调试(strace、 pstack )
nginx源码分析--使用GDB调试(strace. pstack ) http://blog.csdn.net/scdxmoe/article/details/49070577
- tab切换 jQuery
$('p.guidan-load1').click(function(){ $("p.guidan-load1").removeClass("guidan-load12& ...
- Hive 体系学习
Hive简介 Hive是一个基于Hadoop的数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并使用HQL作为查询接口.HDFS作为存储底层.MapReduce作为执行层,将HQL语句转换成M ...
- Oracle数据库共享内存分配不足问题的解决
问题: ORA-: unable to allocate bytes of shared memory ("shared pool,)","session param v ...
- 前端自动化gulp遇上es6从 无知到深爱
Gulp是什么? Gulp是前端自动化的工具,但Gulp能用来做什么 1.搭建web服务器 2.使用预处理器Sass,Less 3.压缩优化,可以压缩JS CSS Html 图片 4.自动将更新变化的 ...
- es6 map数据类型,要比set还很多
首先它支持多数据存储,具有增删查功能 set()设置 get()获取; has()查找; delete('obj')删除指定:clear()全部删除 size长度 let json={ name:&q ...