题意描述:

N 个草丛,M 条单向的小道,经过每条道时可以采走这条道上的所有蘑菇,蘑菇有一个恢复系数,即在采过这一片蘑菇后又会新长出蘑菇,求从给定的点出发能采到的蘑菇最大值。

算法分析:

很容易想到最后要求一个最大值,可以用树形 DP,不过本人比较懒,推荐 spfa 求最长路,既好理解又好写。

首先明确一点,如果走到一个环中,里面的所有蘑菇包括每一次恢复后新长出来的蘑菇都能采到。

于是想到了什么? Tarjan 缩点,成为一个有向无环图,把每一个强连通分量里面的蘑菇总数求出来,最后跑一边最长路即可。

然后要注意细节:这道题不需要用 double 存,会有精度问题。可以在存图的时候先把 k 乘 10,在后面的处理中把 k 除以 10 就行了。

代码+注释:

#include<bits/stdc++.h>
using namespace std;
inline int read(){ //快读不解释了int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch == '-') f=-1 ; ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;
}
const int M = 4e5+10;
stack<int>s; //tarjan里面用
queue<int>q; //spfa求最长路的时候用
int n,m,ss;
int cnt1,cnt2,dfncnt,scccnt,ans;
int head1[M],head2[M],dfn[M],low[M],sccnum[M],sccsize[M];
int dis[M],vis[M],sum[M];
struct edge{ //边,定义结构体变量int from,to,nxt,w,k;
}e1[M],e2[M];
void add1(int u,int v,int w,int k){ //跑tarjan用的图e1[++cnt1].to = v;e1[cnt1].from = u;e1[cnt1].w = w;e1[cnt1].nxt = head1[u];head1[u] = cnt1;e1[cnt1].k = k;
}
void add2(int u,int v,int w){ //跑spfa用的图e2[++cnt2].to = v;e2[cnt2].w = w;e2[cnt2].nxt = head2[u];head2[u] = cnt2;
}
void tarjan(int u){ //targan版子dfn[u] = low[u] = ++dfncnt; //时间戳s.push(u);for(register int i(head1[u]) ; i ; i=e1[i].nxt){int v = e1[i].to;if(!dfn[v]){tarjan(v);low[u] = min(low[u],low[v]);}else if(!sccnum[v]) low[u] = min(low[u],dfn[v]);}if(dfn[u] == low[u]){scccnt++;while(1){int x = s.top();s.pop();sccnum[x] = scccnt; //记录下来该点在哪个强连通分量中sccsize[scccnt]++;if(x == u) break; //已经把元素从栈中弹出了}}
}
void spfa(int s){memset(dis,-1,sizeof(dis)); //别忘了每次都要清memset(vis,0,sizeof(vis));dis[s] = sum[s]; //初始化vis[s] = 1;q.push(s);while(!q.empty()){int u = q.front();q.pop();vis[u] = 0;for(register int i(head2[u]) ; i ; i=e2[i].nxt){int v = e2[i].to,w = e2[i].w;if(dis[v] < dis[u] + w + sum[v]){ //别忘了要加上sum[v]dis[v] = dis[u] + w + sum[v]; //最长路!if(!vis[v]){vis[v] = 1;q.push(v);}}}}
}
signed main(){n=read();m=read();for(register int i(1) ; i<=m ; i=-~i){int u,v,w;double k;scanf("%d%d%d%lf",&u,&v,&w,&k);add1(u,v,w,k*10); //先把k*10加入边中}for(register int i(1) ; i<=n ; i=-~i) if(!dfn[i]) tarjan(i);for(register int i(1) ; i<=m ; i=-~i){int x = e1[i].from,y = e1[i].to,w = e1[i].w,k = e1[i].k;if(sccnum[x] == sccnum[y]){while(w){sum[sccnum[x]] += w; //这一个强连通分量里的总价值w = w * k / 10; //前面乘10,这里除掉}}else add2(sccnum[x],sccnum[y],w); //第二次加边}ss = read();ss = sccnum[ss];spfa(ss); //从这个点开始走最长路for(register int i(1) ; i<=scccnt ; i=-~i) ans = max(ans,dis[i]); //由于不知道终点是哪个,把每个点都扫一遍取最大就行了printf("%d",ans);return 0;
}

洛谷 P2656 采蘑菇相关推荐

  1. Luogu P2656 采蘑菇

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

  2. 洛谷 P2056 采花

    题目描述 萧芸斓是 Z国的公主,平时的一大爱好是采花. 今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花.花园足够大,容纳了 n 朵花,花有 c 种颜色(用整数 1-c 表示) ,且花是排成 ...

  3. 洛谷P2056 采花

    题目描述 萧芸斓是 Z国的公主,平时的一大爱好是采花. 今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花.花园足够大,容纳了 n 朵花,花有 c 种颜色(用整数 1-c 表示) ,且花是排成 ...

  4. 洛谷 P2056 采花 - 莫队算法

    萧芸斓是 Z国的公主,平时的一大爱好是采花. 今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花.花园足够大,容纳了 n 朵花,花有 c 种颜色(用整数 1-c 表示) ,且花是排成一排的,以 ...

  5. 洛谷P4113 [HEOI2012]采花 题解

    洛谷P4113 [HEOI2012]采花 题解 题目链接:P4113 [HEOI2012]采花 题意:萧薰儿是古国的公主,平时的一大爱好是采花. 今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园 ...

  6. 洛谷刷题C语言:LJESTVICA、FUNGHI、LJESNJAK、AUTORI、PLANINA

    记录洛谷刷题QAQ [COCI2012-2013#5] LJESTVICA 题目背景 Veronica 在音乐学院上学,她拿到了一张只有音符的乐谱,并且需要识别其所使用的音阶. 题目描述 在这个问题中 ...

  7. 信息学奥赛一本通 1927:【04NOIP普及组】花生采摘 | OpenJudge NOI 1.13 38:花生采摘 | 洛谷 P1086 [NOIP2004 普及组] 花生采摘

    [题目链接] ybt 1927:[04NOIP普及组]花生采摘 OpenJudge NOI 1.13 38:花生采摘 洛谷 P1086 [NOIP2004 普及组] 花生采摘 [题目考点] 1. 模拟 ...

  8. 洛谷-题解 P2672 【推销员】

    独门思路!链表加优先队列! 这题一望,贪心是跑不掉了,但是我贪心并不好,所以想到了一个复杂一些但思路更保稳的做法 思路: 1 因为是离线操作,所以我们可以倒着求,先求x=n的情况,因为那样直接就知道了 ...

  9. 洛谷 P1142 轰炸

    洛谷 P1142 轰炸 题目描述 "我该怎么办?"飞行员klux向你求助. 事实上,klux面对的是一个很简单的问题,但是他实在太菜了. klux要想轰炸某个区域内的一些地方,它们 ...

最新文章

  1. 奈奎斯特采样定理_通俗理解奈奎斯特带宽
  2. 【Codeforces 339C】Xenia and Weights
  3. 【Python】圆周率的计算
  4. 为什么没有看到webcontent_环卫工人工资低工作辛苦,为什么还有那么多人愿意做呢?...
  5. 从0到1入门:7天玩转IoT物联网实战营丨IoT喊你加入学习之旅!
  6. java 依赖其他项目时如何导出_使用Eclipse将具有外部依赖性的Java项目导出到jar...
  7. 为了搞懂什么是区块链,我都快抑郁了(转)
  8. PyTorch 入坑五 autograd与逻辑回归
  9. 将windows项目移植到linux上
  10. ST 电机库 电机位置环7天冲刺开发
  11. Visio2016 安装教程
  12. Android自带的抓包工具tcpdump
  13. 实战:tomcat版本升级
  14. linux信号灯超时时间已到,急!!信号灯超时时间已到错误又出来了!!!!
  15. php表格链接地址,php代码链接数据库并以表格形式输出数据库中的数据功能
  16. mac 下禁止顽固的开机程序自启
  17. 电脑文件夹拒绝访问,如何解决?
  18. FMSoft uniGUI 1.9.x,开发经验扩展到了一个新的维度
  19. 有线电视显示无服务器,有线电视常见故障排查指南!只需这几招,就能轻松搞定...
  20. 夺命雷公狗—angularjs—10—angularjs里面的内置函数

热门文章

  1. 优化家里网速,以TL-WR842N为例
  2. 计算机专业英语第04章,2021计算机专业英语第四章
  3. Qt修改鼠标样式为自定义图标
  4. 图形开发——显卡学习
  5. 旅行照片剪辑--青岛篇
  6. C语言基础 初识c语言
  7. Stata:边际效应分析\交乘项的系数含义和图示
  8. 穷人最缺少的不是金钱,而是野心
  9. Trafodion事务管理简述
  10. 听说你的程序又双叒叕乱码了