zoukankan      html  css  js  c++  java
  • [SDOI2013]费用流

    嘟嘟嘟

    看到这题目如果想费用流的话就gg了,就像LCA这道题一样,不要被题目迷惑……

    我们考虑Bob,他想让总费用最大,那么他的所有费用一定都加到流量最大的那一条边上。而Alice想让总费用最小,那么就是让流量最大的那一条边最小,自然就想到二分边的容量啦!

    不过这道题特殊的地方是要实数二分。其实终止条件就是当R - L小于自己设定的一个精度。然后如果当前不符合,不应该是L = mid + 1,因为(mid, mid + 1)中很有可能是答案,所以应该是L = mid +eps。

    第一次写实数二分,总是死循环,调了有那么一会儿……

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cmath>
      4 #include<algorithm>
      5 #include<cstring>
      6 #include<cstdlib>
      7 #include<cctype>
      8 #include<vector>
      9 #include<stack>
     10 #include<queue>
     11 using namespace std;
     12 #define enter puts("") 
     13 #define space putchar(' ')
     14 #define Mem(a, x) memset(a, x, sizeof(a))
     15 #define rg register
     16 typedef long long ll;
     17 typedef double db;
     18 const int INF = 0x3f3f3f3f;
     19 const db eps = 1e-8;
     20 const int maxn = 105;
     21 inline ll read()
     22 {
     23     ll ans = 0;
     24     char ch = getchar(), last = ' ';
     25     while(!isdigit(ch)) {last = ch; ch = getchar();}
     26     while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();}
     27     if(last == '-') ans = -ans;
     28     return ans;
     29 }
     30 inline void write(ll x)
     31 {
     32     if(x < 0) x = -x, putchar('-');
     33     if(x >= 10) write(x / 10);
     34     putchar(x % 10 + '0');
     35 }
     36 
     37 int n, m, p, Max;
     38 
     39 struct Edge
     40 {
     41     int from, to;
     42     db cap, flow;
     43 };
     44 vector<Edge> edges;
     45 vector<int> G[maxn];
     46 void addEdge(int from, int to, int w)
     47 {
     48     edges.push_back((Edge){from, to, (db)w, 0});
     49     edges.push_back((Edge){to, from, 0, 0});
     50     int sz = edges.size();
     51     G[from].push_back(sz - 2);
     52     G[to].push_back(sz - 1);
     53 }
     54 
     55 int dis[maxn];
     56 bool bfs()
     57 {
     58     Mem(dis, 0); dis[1] = 1;
     59     queue<int> q; q.push(1);
     60     while(!q.empty())
     61     {
     62         int now = q.front(); q.pop();
     63         for(int i = 0; i < (int)G[now].size(); ++i)
     64         {
     65             Edge& e = edges[G[now][i]];
     66             if(!dis[e.to] && e.cap > e.flow + eps)
     67             {
     68                 dis[e.to] = dis[now] + 1;
     69                 q.push(e.to);    
     70             }
     71         }
     72     }
     73     return dis[n];
     74 }
     75 int cur[maxn];
     76 db dfs(int now, db res)
     77 {
     78     if(now == n || res == 0) return res;
     79     db flow = 0, f;
     80     for(int& i = cur[now]; i < (int)G[now].size(); ++i)
     81     {
     82         Edge& e = edges[G[now][i]];
     83         if(dis[e.to] == dis[now] + 1 && (f = dfs(e.to, min(res, e.cap - e.flow))) > 0)
     84         {
     85             e.flow += f;
     86             edges[G[now][i] ^ 1].flow -= f;
     87             flow += f; res -= f;
     88             if(res == 0) break;
     89         }
     90     }
     91     return flow;
     92 }
     93 
     94 db maxflow()
     95 {
     96     db flow = 0;
     97     while(bfs())
     98     {
     99         Mem(cur, 0);
    100         flow += dfs(1, (db)INF);
    101     }
    102     return flow;
    103 }
    104 
    105 void build_Gra(db x)        //不用重建,修改每一条边的参数就行 
    106 {
    107     for(int i = 0; i < (int)edges.size(); i += 2)
    108     {
    109         edges[i].cap = x; edges[i].flow = 0;
    110         edges[i ^ 1].cap = 0; edges[i ^ 1].flow = 0;
    111     }
    112 }
    113 
    114 int main()
    115 {
    116     n = read(); m = read(); p = read();
    117     for(int i = 1; i <= m; ++i)
    118     {
    119         int x = read(), y = read(), w = read();
    120         addEdge(x, y, w);
    121     }
    122     Max = maxflow();
    123     db L = 0, R = (db)INF;
    124     while(L < R - eps)
    125     {
    126         db mid = (L + R) / 2.00;
    127         build_Gra(mid);
    128         if(maxflow() > (db)Max - eps) R = mid;
    129         else L = mid + eps;
    130     }
    131     printf("%d %.6lf
    ", Max, (L + R) / 2.00 * p);
    132     return 0;
    133 }
    View Code
  • 相关阅读:
    Spring Boot 启动(二) Environment 加载
    Spring Boot 启动(一) SpringApplication 分析
    Java 正则表达式之捕获组
    kylin 系列(一)安装部署
    CDH 安装
    JVM 字节码(四)静态方法、构造代码、this 以及 synchronized 关键字
    JVM 字节码(三)异常在字节码中的处理(catch 和 throws)
    JVM 字节码(二)方法表详解
    JVM 字节码(一)字节码规范
    Hadoop 系列(三)Java API
  • 原文地址:https://www.cnblogs.com/mrclr/p/9700934.html
Copyright © 2011-2022 走看看