码迷,mamicode.com
首页 > 其他好文 > 详细

IndiaHacks 2016 - Online Edition (Div. 1 + Div. 2) 二分答案 + 网络流

时间:2016-03-20 21:26:32      阅读:368      评论:0      收藏:0      [点我收藏+]

标签:

  这道题的意思是给你一个有向图, 每条边上有一个最大载重量, 现在有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(" ----------- \n");
//    for(int i=0; i<di2.e.size(); i++) {
//        if(di2.e[i].cap) printf("%d %d %d\n", 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\n", res);
    return 0;
}

 

IndiaHacks 2016 - Online Edition (Div. 1 + Div. 2) 二分答案 + 网络流

标签:

原文地址:http://www.cnblogs.com/xingxing1024/p/5299564.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!