• BZOJ 4898 [APIO2017] 商旅 | SPFA判负环 分数规划


    BZOJ 4898 [APIO2017] 商旅 | SPFA判负环 分数规划

    更清真的题面链接:https://files.cnblogs.com/files/winmt/merchant(zh_CN).pdf

    题解

    ……APIO2017那天我似乎在……北京一日游……

    【更新】诶?我……我Rank1了?//虽然只有不几个人做这道题


    正经的题解:

    二分答案,如果存在一种环路使得【总获利/总路程 > mid】,那么这个环路的【总(获利 - 路程 * mid)】一定大于0,换句话说,把边权换成【获利 - 路程 * mid】后,该图有正环。

    正环可以用DFS版SPFA判,详见这篇论文——SPFA算法的优化及应用,每对点对(u, v)的获利、最短路程都可以预处理出来。

    那么这道题还是很简单的啦。

    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    #define space putchar(' ')
    #define enter putchar('
    ')
    using namespace std;
    typedef long long ll;
    template <class T>
    void read(T &x){
        char c;
        bool op = 0;
        while(c = getchar(), c < '0' || c > '9')
        if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
        x = x * 10 + c - '0';
        if(op) x = -x;
    }
    template <class T>
    void write(T x){
        if(x < 0) putchar('-'), x = -x;
        if(x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    
    const int N = 105, MAXK = 1005,  INF = 0x3f3f3f3f;
    int n, m, K, dis[N][N], val[N][N], buy[N][MAXK], sell[N][MAXK];
    double l, r, mid, d[N];
    bool done, ins[N];
    
    void spfa(int u){
        if(done) return;
        ins[u] = 1;
        for(int v = 1; v <= n; v++){
            if(done) return;
            if(v != u && dis[u][v] < INF && d[u] + val[u][v] - mid * dis[u][v] > d[v]){
                d[v] = d[u] + val[u][v] - mid * dis[u][v];
                if(ins[v]) return (void)(done = 1);
                spfa(v);
            }
        }
        ins[u] = 0;
    }
    bool check(){
        done = 0;
        memset(ins, 0, sizeof(ins));
        memset(d, 0, sizeof(d));
        for(int i = 1; i <= n && !done; i++)
            spfa(i);
        return done;
    }
    
    int main(){
    
        read(n), read(m), read(K);
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= K; j++)
                read(buy[i][j]), read(sell[i][j]);
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++)
                dis[i][j] = i == j ? 0 : INF;
        for(int i = 1, u, v, w; i <= m; i++)
            read(u), read(v), read(w), dis[u][v] = w;
        for(int k = 1; k <= n; k++)
            for(int i = 1; i <= n; i++)
                for(int j = 1; j <= n; j++)
                    dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++)
                for(int k = 1; k <= K; k++)
                    if(buy[i][k] != -1 && sell[j][k] != -1){
                        val[i][j] = max(val[i][j], sell[j][k] - buy[i][k]);
                        r = max(r, (double)val[i][j]);
                    }
        int cnt = 0;
        while(++cnt <= 60){
            mid = (l + r) / 2;
            if(check()) l = mid;
            else r = mid;
        }
        printf("%lld
    ", (ll)floor((l + r) / 2));
        
        return 0;
    }
    
  • 相关阅读:
    盗COOKIE之方法总结
    会话追踪(session tracking)
    XSS盗COOKIE
    ActiveX 控件漏洞挖掘之方法
    Windows之权限讲解
    Centos网络配置小工具
    区分一下dpkg,rpm和yum以及apt-get
    Java中弹出框的集中方式
    Spring3 MVC请求参数获取的几种方法
    Spring自带配置方式链接数据库(没有src新建文件,没有c3p0)
  • 原文地址:https://www.cnblogs.com/RabbitHu/p/BZOJ4898.html
Copyright © 2020-2023  润新知