• IndiaHacks 2016


      这道题的意思是给你一个有向图, 每条边上有一个最大载重量, 现在有x头牛要从顶点1走向顶点n, 每头牛要载的重量都是一样的, 问你最多能载多少的重量? 可以二分答案, 算出每头牛的载重, 然后修改边权, 跑一次最大流即可判断当前答案是否正确, 二分答案即可, 注意由于原始边权/每头牛的载重量可能会很大, 因此我们在修改边权时应该注意这一点,将边权的最大值控制在1000000之内, 防止溢出, 代码如下:

    #include <bits/stdc++.h>
    
    using namespace std;
    const int maxn = 100;
    int n, m, x;
    
    
    struct Dinic{
        int n;
        struct edge {int from, to, cap;};
        vector<int> G[maxn];
        vector<edge> e;
        int level[maxn], iter[maxn];
        void init() {
            for(int i=0; i<=n; i++) G[i].clear();
            e.clear();
        }
        void add_edge(int u, int v, int cap){
            e.push_back((edge){u, v, cap});
            e.push_back((edge){v, u, 0});
            int m = e.size();
            G[u].push_back(m-2);
            G[v].push_back(m-1);
        }
        void bfs(int s){
            memset(level, -1, sizeof(level));
            queue<int> que;
            level[s] = 0;
            que.push(s);
            while(!que.empty()) {
                int u = que.front(); que.pop();
                for(int i=0; i<G[u].size(); i++) {
                    edge &te = e[G[u][i]];
                    if(te.cap>0 && level[te.to]<0){
                        level[te.to] = level[u] + 1;
                        que.push(te.to);
                    }
                }
            }
        }
        int dfs(int v, int t, int f){
            if(v == t) return f;
            for(int &i=iter[v]; i<G[v].size(); i++){
                edge &tpe = e[G[v][i]];
                if(tpe.cap>0 && level[v]<level[tpe.to]){
                    int d = dfs(tpe.to, t, min(f, tpe.cap));
                    if(d > 0) {
                        tpe.cap -= d;
                        e[G[v][i]^1].cap += d;
                        return d;
                    }
                }
            }
            return 0;
        }
        int max_flow(int s, int t){
            int flow = 0;
            for( ;; ){
                bfs(s);
                if(level[t]<0) return flow;
                memset(iter, 0, sizeof(iter));
                int f;
                while((f=dfs(s, t, 0x3f3f3f3f)) > 0) flow += f;
            }
        }
    }di, di2;
    
    bool check(double mid) {
        double eve = mid/(double)x;
        di2 = di;
        for(int i=0; i<di2.e.size(); i++) {
            di2.e[i].cap = min((double)di2.e[i].cap/eve, (double)1000000+100);
        }
    //    printf(" ----------- 
    ");
    //    for(int i=0; i<di2.e.size(); i++) {
    //        if(di2.e[i].cap) printf("%d %d %d
    ", di2.e[i].from, di2.e[i].to, di2.e[i].cap);
    //    }
        int res = di2.max_flow(1, n);
        return res >= x;
    }
    
    int main() {
        scanf("%d%d%d", &n, &m, &x);
        di.n = n;
        di.init();
        for(int i=0; i<m; i++){
            int u, v, c;
            scanf("%d%d%d", &u, &v, &c);
            di.add_edge(u, v, c);
        }
        double l=0, r=(double)0x3f3f3f3f;
        double res = 0;
        for(int i=0; i<1000; i++) {
            double mid = (l+r)/2;
            if(check(mid)){
                res = mid;
                l = mid;
            } else r = mid;
        }
        printf("%.10f
    ", res);
        return 0;
    }
  • 相关阅读:
    转 -- Linux系列:Ubuntu虚拟机设置固定IP上网(配置IP、网关、DNS、防止resolv.conf被重写)
    转 -- 求一个二进制数值中的1的个数
    ubuntu 搭建 samba 服务器
    64bit ubuntu 安装32bit的软件
    ubuntu 添加管理员账户
    #ifdef 和 #if defined 的区别 -- 转
    xming + putty 搭建远程图形化ssh访问ubuntu 14.04
    ubuntu 安装bochs
    强制类型转换中的精度丢失
    转载 -- 如何判断Javascript对象是否存在
  • 原文地址:https://www.cnblogs.com/xingxing1024/p/5299564.html
Copyright © 2020-2023  润新知