题目大意:
  给你一个有向图,每条边有一个边权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]采蘑菇的更多相关文章

  1. [Luogu 2656] 采蘑菇

    Description 小胖和ZYR要去ESQMS森林采蘑菇. ESQMS森林间有N个小树丛,M条小径,每条小径都是单向的,连接两个小树丛,上面都有一定数量的蘑菇.小胖和ZYR经过某条小径一次,可以采 ...

  2. 【Foreign】采蘑菇 [点分治]

    采蘑菇 Time Limit: 20 Sec  Memory Limit: 256 MB Description Input Output Sample Input 5 1 2 3 2 3 1 2 1 ...

  3. 洛谷——P2656 采蘑菇

    P2656 采蘑菇 题目描述 小胖和ZYR要去ESQMS森林采蘑菇. ESQMS森林间有N个小树丛,M条小径,每条小径都是单向的,连接两个小树丛,上面都有一定数量的蘑菇.小胖和ZYR经过某条小径一次, ...

  4. 洛谷—— P2656 采蘑菇

    https://www.luogu.org/problem/show?pid=2656 题目描述 小胖和ZYR要去ESQMS森林采蘑菇. ESQMS森林间有N个小树丛,M条小径,每条小径都是单向的,连 ...

  5. 【细节题 离线 树状数组】luoguP4919 Marisa采蘑菇

    歧义差评:但是和题意理解一样了之后细节依然处理了很久,说明还是水平不够…… 题目描述 Marisa来到了森林之中,看到了一排nn个五颜六色的蘑菇,编号从1-n1−n,这些蘑菇的颜色分别为col[1], ...

  6. F 采蘑菇的克拉莉丝

    这是一道树链剖分的题目: 很容易想到,我们在树剖后,对于操作1,直接单点修改: 对于答案查询,我们直接的时候,我们假设查询的点是3,那么我们在查询的时候可分为两部分: 第一部分:查找出除3这颗子树以外 ...

  7. Luogu P2656 采蘑菇

    尽管是缩点的习题,思路也是在看了题解后才明白的. 首先,每个强连通分量内的点都是一定互通的,也就是可以完全把这里面的边都跑满,摘掉所有能摘的蘑菇.那么,考虑给每一个强连通分量化为的新点一个点权,代表摘 ...

  8. [Luogu1119]采蘑菇

    题目大意: 给你一个无向图,点i在时间t[i]之前是不存在的,有q组询问,问你时间为t时从x到y的最短路. 点的编号按出现的时间顺序给出,询问也按照时间顺序给出. 思路: Floyd. Floyd的本 ...

  9. Wannafly Camp 2020 Day 2F 采蘑菇的克拉莉丝 - 树链剖分

    如果暴力维护,每次询问时需要对所有孩子做计算 考虑通过树剖来平衡修改与询问的时间,询问时计算重链和父树,轻链的贡献预先维护好,修改时则需要修改可能影响的轻链贡献,因为某个点到根的路径上轻重交替只有 \ ...

随机推荐

  1. Linux目录结构与文件权限——(五)

    1.目录结构

  2. centos 搭建 ss

    download:https://files.cnblogs.com/files/xishaonian/ShadowsocksR-4.7.0-win.7z 使用方法:使用root用户登录,运行以下命令 ...

  3. Java21个基础知识点

    类装载器就是寻找类的字节码文件,并构造出类在JVM内部表示的对象组件.在Java中,类装载器把一个类装入JVM中,要经过以下步骤: (1) 装载:查找和导入Class文件: (2) 链接:把类的二进制 ...

  4. C++之初始化问题

    首先,我们应该明确的是在C++中初始化不是赋值,因为初始化是必要的,如果读取了未初始化的值将会导致不明确的行为.初始化指创建变量并且给它赋初值,而赋值则是擦除对象的当前值并用新值代替.C++支持两种初 ...

  5. 使用IDA PRO+OllyDbg+PEview 追踪windows API 动态链接库函数的调用过程

    使用IDA PRO+OllyDbg+PEview 追踪windows API 动态链接库函数的调用过程 http://blog.csdn.net/liujiayu2/article/details/5 ...

  6. 【学习笔记】动态树Link-Cut-Tree

    这是两个月前写的,看能不能搬运过来…… 动态树是一类维护森林连通性的问题(已纠正,感谢ZQC巨佬),目前最(wo)常(zhi)见(hui)的动态树就是LCT(Link-Cut-Tree),然而LCT似 ...

  7. Hadoop-MR[会用]MR程序的运行模式

    1.简介 现在很少用到使用MR计算框架来实现功能,通常的做法是使用hive等工具辅助完成.但是对于其底层MR的原理还是有必要做一些了解. 2.MR客户端程序实现套路 这一小节总结归纳编写mr客户端程序 ...

  8. 如何生成[0,maxval]范围内m个随机整数的无重复的有序序列

    在这里我们将待生成的数据结构称为IntSet,接口定义如下: class IntSetImp { public: IntSetImp(int maxelements,int maxval); void ...

  9. 一个大div里面包裹一个小div,里面的小div的点击事件不触发外面的这个大div的点击事件

    一开始上html代码 <div id="div1" style="background: blue;width: 100px; height: 100px;&quo ...

  10. poj 2452(RMQ+二分查找)

    题目链接: http://poj.org/problem?id=2452 题意:在区间[1,n]上找到满足 a[i]<a[k]<a[j] (i<=k<=j) 的最大子区间 (j ...