洛谷 P2656 采蘑菇

来源:互联网 发布:有毒网络剧百度云资源 编辑:程序博客网 时间:2024/04/28 17:28

洛谷 P2656 采蘑菇

题目描述

小胖和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缩点求强连通分量再重建图,spfa跑最长路。

题解:

#include<iostream>#include<cstdio>#include<queue>#include<stack>using namespace std;const int maxn=400000+10;struct cc{    int from,to,cost;    double xs;}es[maxn],es1[maxn];int first[maxn],nxt[maxn];int first1[maxn],nxt1[maxn];int tot=0;void build(int ff,int tt,int pp,double dd){    es[++tot]=(cc){ff,tt,pp,dd};    nxt[tot]=first[ff];    first[ff]=tot;}int tot1=0;void build1(int ff,int tt,int pp){    es1[++tot1]=(cc){ff,tt,pp};    nxt1[tot1]=first1[ff];    first1[ff]=tot1;}int low[maxn],dfn[maxn];stack<int>s;int scc_num[maxn];int cnt=0,scc_cnt=0;int dfs(int u)//tarjan {    low[u]=dfn[u]=++cnt;    s.push(u);    for(int i=first[u];i;i=nxt[i])    {        int v=es[i].to;        if(!dfn[v])        {            low[v]=dfs(v);            low[u]=min(low[u],low[v]);        }        else if(!scc_num[v])        {            low[u]=min(low[u],dfn[v]);        }    }    if(low[u]==dfn[u])    {        scc_cnt++;        while(!s.empty())        {            int v=s.top(); s.pop();            scc_num[v]=scc_cnt;            if(u==v)            {                break;            }        }    }    return low[u];}int d[maxn];//存强连通分量的点权 bool vis[maxn];queue<int>q;void pre(int u){    for(int i=first[u];i;i=nxt[i])    {        int v=es[i].to;        if(scc_num[u]==scc_num[v])//计算         {            while(es[i].cost)            {                d[scc_num[u]]+=es[i].cost;                es[i].cost*=es[i].xs;            }        }        else//建边         {            build1(scc_num[u],scc_num[v],es[i].cost);        }    }}int dis[maxn];void spfa(int s){    q.push(s);    vis[s]=1;    while(!q.empty())    {        int u=q.front(); q.pop();        vis[u]=0;        for(int i=first1[u];i;i=nxt1[i])        {            int v=es1[i].to;            if(dis[v]<dis[u]+es1[i].cost+d[v])            {                dis[v]=d[v]+dis[u]+es1[i].cost;                if(!vis[v])                {                    vis[v]=1;                    q.push(v);                }            }        }    }}int main(){    int n,m;    scanf("%d%d",&n,&m);    for(int i=1;i<=m;i++)    {        int x,y,z;        double t;        scanf("%d%d%d%lf",&x,&y,&z,&t);        build(x,y,z,t);    }    int s;    scanf("%d",&s);    for(int i=1;i<=n;i++)    {        if(!dfn[i])        {            dfs(i);//tarjan缩点         }    }    for(int i=1;i<=n;i++)    {        pre(i);//算出每个强连通分量里可以采的蘑菇数量并重建边     }    for(int i=1;i<=scc_cnt;i++)    {        dis[i]=d[i];    }    spfa(scc_num[s]);    int ans=0;    for(int i=1;i<=scc_cnt;i++)    {        ans=max(ans,dis[i]);    }    printf("%d",ans);    return 0;}
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 七个月宝宝消化不良怎么办 宝宝上火不拉屎怎么办 三天没拉大便怎么办 宝宝肚子胀积食怎么办 2岁宝宝不消化怎么办 宝宝吃多不消化怎么办 宝贝不消化吐了怎么办 五天没解大便怎么办 婴儿便秘有血怎么办 宝宝大便稀酸臭怎么办 婴儿的屎有酸味怎么办 宝宝解绿色大便怎么办 婴儿大便绿色稀怎么办 新生儿十天拉稀怎么办 16天新生儿便秘怎么办 50天新生儿便秘怎么办 18天新生儿便秘怎么办 5天新生儿便秘怎么办 13天新生儿便秘怎么办 宝宝吃米粉便秘怎么办 吃奶的宝宝便秘怎么办 母乳喂养的宝宝便秘怎么办 纯母乳宝宝便秘怎么办 六月大宝宝便秘怎么办 喝母乳宝宝便秘怎么办 宝宝喝奶粉便秘怎么办 小孩上火拉不出粑粑怎么办 宝宝上火拉不出粑粑怎么办 新生宝宝不大便怎么办 宝宝几天不大便怎么办 40天宝宝便秘怎么办 半个月宝宝便秘怎么办 30天新生儿便秘怎么办 婴儿睡觉抱着睡放不下怎么办 宝宝拉绿大便怎么办 喝奶粉孩子便秘怎么办 吃奶粉便秘是怎么办 婴儿蛋花样大便怎么办 婴儿拉肚子吃药不好怎么办 奶粉引起的便秘怎么办 4天没大便怎么办