zoukankan      html  css  js  c++  java
  • 洛谷——P2656 采蘑菇

    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<cstdio>
    #include<iostream>
    #include<cstring>
    #include<stack>
    #include<queue>
    #define N 10101010
    
    using namespace std;
    
    int n,m,head[N],tot,tpt,phead[N],w[N],s,ans;
    struct bode{
        int to,next,w;
        double f;
    }e[N],p[N];
    void add(int u,int v,int w,double f,bool flg){
        if(flg) e[++tot].to=v,e[tot].next=head[u],head[u]=tot,e[tot].w=w,e[tot].f=f;
        else p[++tpt].to=v,p[tpt].next=phead[u],phead[u]=tpt,p[tpt].w=w,p[tpt].f=f;
    }
    
    int dfn[N],low[N],item,cnt,belong[N];
    bool vis[N];
    stack<int>S;
    void tarjan(int u){
        dfn[u]=low[u]=++item;
        vis[u]=1;S.push(u);
        for(int i=head[u];i;i=e[i].next){
            int v=e[i].to;
            if(!dfn[v]){
                tarjan(v);
                low[u]=min(low[u],low[v]);
            }else if(vis[v]) low[u]=min(low[u],dfn[v]);
        }
        if(low[u]==dfn[u]){
            int v=u;++cnt;
            do{
                v=S.top();S.pop();
                vis[v]=0;belong[v]=cnt;
            }while(v!=u);
        }
    }
    
    int wh(int W,double f){
        int an=0;
        while(W){
            an+=W;
            W*=f;
        }
        return an;
    }
    
    queue<int>Q;
    int d[N];
    void spfa(){
        memset(vis,0,sizeof(vis));
    //    memset(d,0x3f,sizeof(d));
        Q.push(belong[s]);vis[belong[s]]=1;d[belong[s]]=-w[belong[s]];
    //    for(int i=1;i<=cnt;i++) d[i]-=w[i];
        while(!Q.empty()){
            int u=Q.front();Q.pop();vis[u]=0;
            for(int i=phead[u];i;i=p[i].next){
                int v=p[i].to;
                if(d[v]>d[u]-p[i].w){
                    d[v]=d[u]-p[i].w;
                    d[v]-=w[v];w[v]=0;
                    if(!vis[v]){
                        Q.push(v);
                        vis[v]=1;
                    }
                }
            }
        }
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int u,v,W,i=1;i<=m;i++){
            double f;
            scanf("%d%d%d%lf",&u,&v,&W,&f);
            add(u,v,W,f,1);
        }
        for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
        for(int i=1;i<=n;i++){
            for(int j=head[i];j;j=e[j].next){
                int v=e[j].to;
                if(belong[v]!=belong[i]){
                    add(belong[i],belong[v],e[j].w,0,0);
                }else w[belong[i]]+=wh(e[j].w,e[j].f);
            }
        }
        scanf("%d",&s);
        spfa();
        for(int i=1;i<=n;i++) ans=max(ans,-d[i]);
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    学习笔记TF034:实现Word2Vec
    学习笔记TF033:实现ResNet
    学习笔记TF032:实现Google Inception Net
    学习笔记TF031:实现VGGNet
    学习笔记TF030:实现AlexNet
    学习笔记TF029:实现进阶卷积网络
    学习笔记TF028:实现简单卷积网络
    学习笔记TF027:卷积神经网络
    学习笔记TF026:多层感知机
    学习笔记TF025:自编码器
  • 原文地址:https://www.cnblogs.com/song-/p/9571391.html
Copyright © 2011-2022 走看看