洛谷P2656 采蘑菇
来源:互联网 发布:nginx根据不同url跳转 编辑:程序博客网 时间:2024/04/27 23:44
题目描述
小胖和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.
输入输出格式
输入格式: 第一行,N和M
第2……M+1行,每行4个数字,分别表示一条小路的起点,终点,初始蘑菇数,恢复系数。
第M+2行,一个数字S
输出格式: 一个数字,表示最多能采到多少蘑菇,在int32范围内。
输入输出样例
输入样例#1:
3 3
1 2 4 0.5
1 3 7 0.1
2 3 4 0.6
1
输出样例#1:
8
这个题目用来练Tarjan真是太好不过了。刚上来我们就先进行缩点,缩完点后,重新建图,在建图的过程中处理出每个点的点权(缩出来的点如果原本是一个环,我们就不停地跑,每次都给他加上蘑菇数量*恢复系数,直到蘑菇数量为0,这样我们可以知道,这个强连通分量里面的能采到的所有蘑菇数,我们都赋给了这个新点的点权)。这样,我们再跑一边spfa,求一下最长路,这样就保证了我们采到的蘑菇尽量多。正确性显然。
代码如下:
#include<iostream>#include<cstdio>#include<cstdlib>#include<queue>using namespace std;const int maxn=80005;struct dqs{ int f,t,c; double hui;}hh[maxn<<2];struct dqm{ int ff,tt,cc;}ha[maxn<<2];int first[maxn],next[maxn<<2];int tot=0;void build(int f,int t,int c,double hui){ hh[++tot]=(dqs){f,t,c,hui}; next[tot]=first[f]; first[f]=tot;}int lala=0;int fir[maxn],nxt[maxn<<2],d[maxn<<2];bool used[maxn];void add(int f,int t,int c){ ha[++lala]=(dqm){f,t,c}; nxt[lala]=fir[f]; fir[f]=lala;}int tot1=0,snum=0,cnt=0;int dfn[maxn],low[maxn],stack[maxn],jlqlt[maxn],size[maxn],dian[maxn];bool in_stack[maxn]; void group(int x){ dfn[x]=low[x]=++tot1; stack[++snum]=x; in_stack[x]=1; for(int i=first[x];i;i=next[i]) { int u=hh[i].t; if(!dfn[u]) { group(u); low[x]=min(low[x],low[u]); } else if(in_stack[u]) low[x]=min(low[x],dfn[u]); } if(dfn[x]==low[x]) { cnt++; while(true) { jlqlt[stack[snum]]=cnt; size[cnt]++; in_stack[stack[snum]]=0; snum--; if(stack[snum+1]==x) break; } }}queue<int>q;void spfa(int s){ d[s]=dian[s]; q.push(s); used[s]=1; while(!q.empty()) { int x=q.front(); q.pop(); used[x]=0; for(int i=fir[x];i;i=nxt[i]) { int u=ha[i].tt; if(d[u]<d[x]+ha[i].cc) { d[u]=d[x]+ha[i].cc+dian[u]; if(!used[u]) { used[u]=1; q.push(u); } } } }}int n,m,s;int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int f,t,c; double hui; scanf("%d%d%d%lf",&f,&t,&c,&hui); build(f,t,c,hui); } scanf("%d",&s); for(int i=1;i<=n;i++) if(!dfn[i]) group(i); for(int i=1;i<=tot;i++) { int xx,yy; xx=hh[i].f; yy=hh[i].t; if(jlqlt[xx]==jlqlt[yy]) { int d=hh[i].c; while(d) { dian[jlqlt[xx]]+=d; d=d*hh[i].hui; } } else add(jlqlt[xx],jlqlt[yy],hh[i].c); } spfa(jlqlt[s]); int ans=0; for(int i=1;i<=cnt;i++) ans=max(ans,d[i]); printf("%d\n",ans); return 0;}
神犇Loi_a打了拓扑排序,神的不得了啊,Orz。这里在征求他的同意下,也列出他的代码
#include<iostream>#include<cstdio>#include<queue>#include<stack>#include<cstring>#define maxn 80005using namespace std;struct E{ int to,nxt; int d;double w; }b[300005];struct C{ int f,t,d; double w;}cc[200005];int fst[maxn],tot;void build(int f,int t,int d,double w){b[++tot]=(E){t,fst[f],d,w};fst[f]=tot;}int dfs_c;int low[maxn],dfn[maxn];stack<int> S;int sccn[maxn],sz[maxn];int cnt;void dfs(int u){ dfn[u]=low[u]=++dfs_c; S.push(u); for(int i=fst[u];i;i=b[i].nxt) { int v=b[i].to; if(!dfn[v]) { dfs(v); low[u]=min(low[u],low[v]); } else if(!sccn[v]) low[u]=min(low[u],dfn[v]); } if(low[u]==dfn[u]) { cnt++; while(true) { int v=S.top(); S.pop(); sccn[v]=cnt; sz[cnt]++; if(v==u) break; } }}int n,m,st;int val[maxn],dis[maxn];int rd[maxn];queue<int> q;void top(){ q.push(sccn[st]); dis[sccn[st]]=val[sccn[st]]; while(!q.empty()) { int u=q.front(); q.pop(); for(int i=fst[u];i;i=b[i].nxt) { int v=b[i].to; rd[v]--; dis[v]=max(dis[v],dis[u]+val[v]+b[i].d); if(rd[v]==0) q.push(v); } }}int main(){ scanf("%d%d",&n,&m); int s,t,v;double w; for(int i=1;i<=m;i++) { scanf("%d%d%d%lf",&s,&t,&v,&w); cc[i]=(C){s,t,v,w}; build(s,t,v,w); } scanf("%d",&st); dfs(st); memset(fst,0,sizeof(fst)); tot=0; for(int i=1;i<=m;i++) { int f=cc[i].f,t=cc[i].t; if(!sccn[f]) continue; if(sccn[f]==sccn[t]) { int d=cc[i].d; while(d) { val[sccn[f]]+=d; d*=cc[i].w; } } else { build(sccn[f],sccn[t],cc[i].d,cc[i].w); rd[sccn[t]]++; } } top(); int ans=0; for(int i=1;i<=cnt;i++) { ans=max(ans,dis[i]); } printf("%d",ans); return 0;}
- 洛谷 P2656 采蘑菇
- 【洛谷 P2656】采蘑菇
- 洛谷P2656 采蘑菇
- 洛谷 P2656 采蘑菇
- 洛谷P2656 采蘑菇
- 洛谷P2656 采蘑菇
- 【洛谷 P2656】采蘑菇
- 洛谷 P2656 采蘑菇(Tarjan)
- 洛谷2656 采蘑菇
- 洛谷2656 采蘑菇
- 【洛谷 2656】采蘑菇
- 采蘑菇
- 采蘑菇
- qduoj GZS采蘑菇
- [JZOJ5058]采蘑菇
- BOJ 478 小妹妹采蘑菇
- boj478. 小妹妹采蘑菇-概率
- c++游戏设计四:采蘑菇
- UVa11732
- 第一次使用Android Studio
- 字母塔
- mysql数据库备份及恢复
- Django官方教程(四)【创建你的第一个 Django 项目,第二部分】
- 洛谷P2656 采蘑菇
- c语言-爱心代码的实现
- WE,RNG惨败之由
- 数据库顺序栈的实现
- Netty的启动执行过程分析(二)
- MVC5项目发布到IIS
- 字符串的反转
- Linux 彻底卸载mysql 并且重装
- 数组(四)--冒泡排序