[Luogu 2656] 采蘑菇
Description
小胖和ZYR要去ESQMS森林采蘑菇。
ESQMS森林间有N个小树丛,M条小径,每条小径都是单向的,连接两个小树丛,上面都有一定数量的蘑菇。小胖和ZYR经过某条小径一次,可以采走这条路上所有的蘑菇。由于ESQMS森林是一片神奇的沃土,所以一条路上的蘑菇被采过后,又会长出一些新的蘑菇,数量为原来蘑菇的数量乘上这条路的“恢复系数”,再下取整。
比如,一条路上有4个蘑菇,这条路的“恢复系数”为0.7,则第一~四次经过这条路径所能采到的蘑菇数量分别为4,2,1,0.
现在,小胖和ZYR从S号小树丛出发,求他们最多能采到多少蘑菇。
对于30%的数据,N<=7,M<=15
另有30%的数据,满足所有“恢复系数”为0
对于100%的数据,N<=80,000,M<=200,000,0.1<=恢复系数<=0.8且仅有一位小数,1<=S<=N.
Input
第一行,N和M
第2……M+1行,每行4个数字,分别表示一条小路的起点,终点,初始蘑菇数,恢复系数。
第M+2行,一个数字S
Output
一个数字,表示最多能采到多少蘑菇,在int32范围内。
Solution
强联通分量缩点。
记录每个 SCC 内部把所有的边都压榨完之后的权值和 sze[]
然后拓扑跑最长路即可。
upd:第一遍 wa 是因为用了一种自作聪明的在 Tarjan 过程就求 sze 的做法,但是是错的,因为一个包含 n 个点的 SCC 不一定只有 n 条边。
第二遍 wa 是因为数据有自环,所以在计算 sze 的时候不能根据起点和终点求,而是要遍历每条边。
Code
// By YoungNeal
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#define N 80005
#define M 200005 int maxn;
int n,m,s;
bool in[N];
int sze[N];
int dis[N];
int deg[N];
int head2[N];
int stk[N],top;
int cnt,sum,tot;
int c[N],head[N];
int dfn[N],low[N]; struct Edge{
int to,nxt,dis,js;
}edge[M],edge2[M]; void add(int x,int y,int z,int k){
edge[++cnt].to=y;
edge[cnt].nxt=head[x];
edge[cnt].dis=z;
edge[cnt].js=k;
head[x]=cnt;
} void add_c(int x,int y,int z){
edge2[++cnt].to=y;
edge2[cnt].nxt=head2[x];
edge2[cnt].dis=z;
head2[x]=cnt;
} void tarjan(int now){
dfn[now]=low[now]=++sum;
stk[++top]=now;in[now]=;
for(int i=head[now];i;i=edge[i].nxt){
int to=edge[i].to;
if(!dfn[to]) tarjan(to),low[now]=std::min(low[now],low[to]);
else if(in[to]) low[now]=std::min(low[now],low[to]);
}
if(dfn[now]==low[now]){
int y;tot++;
do{
y=stk[top--];
c[y]=tot,in[y]=;
}while(y!=now);
}
} int calc(int a,double b){
int ans=;
while(a){
ans+=a;
a*=b;
}
return ans;
} void toposort(){
std::queue<int> topo;
for(int i=;i<=tot;i++) dis[i]=-2e9;
dis[c[s]]=sze[c[s]];
maxn=dis[c[s]];
for(int i=;i<=tot;i++){
if(!deg[i]) topo.push(i);
}
while(topo.size()){
int u=topo.front();topo.pop();
for(int i=head2[u];i;i=edge2[i].nxt){
int to=edge2[i].to;
dis[to]=std::max(dis[to],dis[u]+sze[to]+edge2[i].dis);
deg[to]--;
if(!deg[to]) topo.push(to);
}
}
for(int i=;i<=tot;i++) maxn=std::max(maxn,dis[i]);
} signed main(){
scanf("%d%d",&n,&m);
for(int a,b,c,i=;i<=m;i++){
double x;
scanf("%d%d%d%lf",&a,&b,&c,&x);
int js=calc(c,x);
add(a,b,c,js);
}
scanf("%d",&s);
cnt=;
for(int i=;i<=n;i++){
if(!dfn[i]) tarjan(i);
}
for(int x=;x<=n;x++){
for(int i=head[x];i;i=edge[i].nxt){
int to=edge[i].to;
if(c[x]!=c[to]) continue;
sze[c[to]]+=edge[i].js;
}
}
for(int x=;x<=n;x++){
for(int i=head[x];i;i=edge[i].nxt){
int to=edge[i].to;
if(c[x]==c[to]) continue;
add_c(c[x],c[to],edge[i].dis);
deg[c[to]]++;
}
}
toposort();
printf("%d\n",maxn);
return ;
}
[Luogu 2656] 采蘑菇的更多相关文章
- Luogu P2656 采蘑菇
尽管是缩点的习题,思路也是在看了题解后才明白的. 首先,每个强连通分量内的点都是一定互通的,也就是可以完全把这里面的边都跑满,摘掉所有能摘的蘑菇.那么,考虑给每一个强连通分量化为的新点一个点权,代表摘 ...
- 洛谷—— P2656 采蘑菇
https://www.luogu.org/problem/show?pid=2656 题目描述 小胖和ZYR要去ESQMS森林采蘑菇. ESQMS森林间有N个小树丛,M条小径,每条小径都是单向的,连 ...
- 【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经过某条小径一次, ...
- 【细节题 离线 树状数组】luoguP4919 Marisa采蘑菇
歧义差评:但是和题意理解一样了之后细节依然处理了很久,说明还是水平不够…… 题目描述 Marisa来到了森林之中,看到了一排nn个五颜六色的蘑菇,编号从1-n1−n,这些蘑菇的颜色分别为col[1], ...
- luogu P2056 采花
题目描述 萧芸斓是 Z国的公主,平时的一大爱好是采花. 今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花.花园足够大,容纳了 n 朵花,花有 c 种颜色(用整数 1-c 表示) ,且花是排成 ...
- F 采蘑菇的克拉莉丝
这是一道树链剖分的题目: 很容易想到,我们在树剖后,对于操作1,直接单点修改: 对于答案查询,我们直接的时候,我们假设查询的点是3,那么我们在查询的时候可分为两部分: 第一部分:查找出除3这颗子树以外 ...
- 洛谷 P2656 采蘑菇 树形DP+缩点+坑点
题目链接 https://www.luogu.com.cn/problem/P2656 分析 这其实是个一眼题(bushi 发现如果没有那个恢复系数,缩个点就完了,有恢复系数呢?你发现这个恢复系数其实 ...
- [Luogu1119]采蘑菇
题目大意: 给你一个无向图,点i在时间t[i]之前是不存在的,有q组询问,问你时间为t时从x到y的最短路. 点的编号按出现的时间顺序给出,询问也按照时间顺序给出. 思路: Floyd. Floyd的本 ...
随机推荐
- 编写高质量iOS与OS X代码的52个有效方法
第一章重点: 第一条:OC的起源 OC由smalltalk语言演化而来的语言为消息结构(messaging structure)语言,其运行时所因执行的的代码由运行环境来决定:函数调用(functio ...
- 1.html基础
认识html 1.1 Hyper text markup language 超文本标记语言. 超文本:超链接.(实现页面跳转) Html结构标准 < ! doctype html> ...
- cxGrid单元格获得输入焦点
cxGrid单元格获得输入焦点 cxGrid单元格获得输入焦点 cxGrid1.SetFocus;cxGrid1DBTableView1.Controller.EditingController. ...
- 如何实现php手机短信验证功能
http://www.qdexun.cn/jsp/news/shownews.do?method=GetqtnewsdetailAction&id=1677 下载php源代码 现在网站在建设网 ...
- PHP内存溢出Allowed memory size of 解决办法
PHP内存溢出Allowed memory size of 解决办法 博客分类: php ============================Allowed memory size of x ...
- string转Date转回String(JAVA)
String dateString = "2012-12-06 "; SimpleDateFormat sdf = new SimpleDateFormat("yyy ...
- [C++基础]队列<queue>中的常用函数
在C++中只要#include<queue>即可使用队列类,其中在面试或笔试中常用的成员函数如下(按照最常用到不常用的顺序) 1. push 2. pop 3. size 4. empty ...
- Redis---quickList(快速列表)
1. 概述 考虑到链表的附加空间相对太高,prev 和 next 指针就要占去 16 个字节 (64bit 系统的指针是 8 个字节),另外每个节点的内存都是单独分配,会加剧内存的碎片化,影响内存管理 ...
- js 的this
js的this应该是不好掌握又必须要掌握的东西 主要参考: http://www.cnblogs.com/pssp/p/5216085.html http://www.cnblogs.com/fron ...
- 【xsy2193】Wallace 最大权闭合子图
题目大意:给你一棵$n$个节点的树$a$,每个点有一个点权$val_i$,同时给你另一棵$n$个节点的树$b$. 现在你需要在树$a$上找一个联通块,满足这些点在树$b$上也是连通的,同时树$a$的这 ...