• codeforces 653D D. Delivery Bears(二分+网络流)


    题目链接:

    D. Delivery Bears

    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Niwel is a little golden bear. As everyone knows, bears live in forests, but Niwel got tired of seeing all the trees so he decided to move to the city.

    In the city, Niwel took on a job managing bears to deliver goods. The city that he lives in can be represented as a directed graph with nnodes and m edges. Each edge has a weight capacity. A delivery consists of a bear carrying weights with their bear hands on a simple path from node 1 to node n. The total weight that travels across a particular edge must not exceed the weight capacity of that edge.

    Niwel has exactly x bears. In the interest of fairness, no bear can rest, and the weight that each bear carries must be exactly the same. However, each bear may take different paths if they like.

    Niwel would like to determine, what is the maximum amount of weight he can deliver (it's the sum of weights carried by bears). Find the maximum weight.

     
    Input
     

    The first line contains three integers nm and x (2 ≤ n ≤ 50, 1 ≤ m ≤ 500, 1 ≤ x ≤ 100 000) — the number of nodes, the number of directed edges and the number of bears, respectively.

    Each of the following m lines contains three integers aibi and ci (1 ≤ ai, bi ≤ nai ≠ bi1 ≤ ci ≤ 1 000 000). This represents a directed edge from node ai to bi with weight capacity ci. There are no self loops and no multiple edges from one city to the other city. More formally, for each i and j that i ≠ j it's guaranteed that ai ≠ aj or bi ≠ bj. It is also guaranteed that there is at least one path from node 1 to node n.

     
    Output
     

    Print one real value on a single line — the maximum amount of weight Niwel can deliver if he uses exactly x bears. Your answer will be considered correct if its absolute or relative error does not exceed 10 - 6.

    Namely: let's assume that your answer is a, and the answer of the jury is b. The checker program will consider your answer correct if .

     
    Examples
     
    input
    4 4 3
    1 2 2
    2 4 1
    1 3 1
    3 4 2
    output
    1.5000000000
    input
    5 11 23
    1 2 3
    2 3 4
    3 4 5
    4 5 6
    1 3 4
    2 4 5
    3 5 6
    1 4 2
    2 5 3
    1 5 2
    3 2 30
    output
    10.2222222222


    题意:

    给一个有向图,有x子熊,每只熊背的重量相同,现在且每条边通过的重量不能超过其容量,问熊背的总重量最大是多少;

    思路:

    二分每个熊背的重量,最后再乘熊的个数就是答案,看这个熊背的重量符合不符合要求时就跑一遍最大流,在寻找增广路径时限制这条流的流量最小值,最后求的每个熊背这么多重量这个网络能允许通过多少只熊,然后与x比较就可以找到答案了,当时有一个最简单的图,他的答案是1,但我一开始输出小数点点后10,精度不够,没过,想想答案最小是1,所以输出了小数点后5位就过了;觉得要是有个答案是1.多的可能就挂了;
    (直接二分答案就好了,可以避免过大的误差,代码改成了直接二分答案的代码了)

    AC代码:
    //#include <bits/stdc++.h>
    #include <vector>
    #include <iostream>
    #include <queue>
    #include <cmath>
    #include <map>
    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    
    using namespace std;
    #define Riep(n) for(int i=1;i<=n;i++)
    #define Riop(n) for(int i=0;i<n;i++)
    #define Rjep(n) for(int j=1;j<=n;j++)
    #define Rjop(n) for(int j=0;j<n;j++)
    #define mst(ss,b) memset(ss,b,sizeof(ss));
    typedef long long LL;
    template<class T> void read(T&num) {
        char CH; bool F=false;
        for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
        for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
        F && (num=-num);
    }
    int stk[70], tp;
    template<class T> inline void print(T p) {
        if(!p) { puts("0"); return; }
        while(p) stk[++ tp] = p%10, p/=10;
        while(tp) putchar(stk[tp--] + '0');
        putchar('
    ');
    }
    
    const LL mod=1e9+7;
    const double PI=acos(-1.0);
    const LL inf=1e14;
    const int N=2e5+15;
    
    int n,m,k,path[52];
    double cap[52][52],temp[52][52],flow[52];
    queue<int>qu;
    double bfs(double x)
    {
        while(!qu.empty())qu.pop();
        mst(path,-1);
        path[1]=0;
        flow[1]=1000001;
        qu.push(1);
        while(!qu.empty())
        {
            int fr=qu.front();
            qu.pop();
            for(int i=1;i<=n;i++)
            {
                if(i!=-1&&temp[fr][i]>=x&&path[i]==-1)
                {
                    path[i]=fr;
                    flow[i]=min(flow[fr],temp[fr][i]);
                    qu.push(i);
                }
            }
        }
        if(path[n]==-1)return -1;
        return flow[n];
    }
    
    int check(double x)
    {
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                temp[i][j]=cap[i][j];
        int sum=0,now,pre;
        while(1)
        {
           double s=bfs(x);
            if(s<0)break;
            int num=floor(s/x);
            sum+=num;
           double f=num*x;
            now=n;
            while(now!=1)
            {
                pre=path[now];
                temp[pre][now]-=f;
                temp[now][pre]+=f;
                now=pre;
            }
        }
        if(sum>=k)return 1;
        return 0;
    }
    
    int main()
    {
        read(n);read(m);read(k);
        int u,v;
       double ca;
        Riep(m)
        {
            read(u),read(v),read(ca);
            cap[u][v]=ca;
        }
       double l=1,r=1000001*(k*1.0);
        while(r-l>1e-8)
        {
           double mid=(l+r)/2;
            if(check(mid/(k*1.0)))l=mid;
            else r=mid;
        }
        printf("%.10lf
    ",r);
            return 0;
    }
    
    
    
     
    
    
    



  • 相关阅读:
    Android笔记之spinner的使用
    Android笔记之AlertDialog使用
    Android笔记之intent使用(一)
    Android笔记之Editext使用
    Android控件之Textiew的使用
    Fastboot常用命令集,完美取代Recovery的所有功能
    Android笔记之WebView
    Android程序下重启手机
    Android笔记之ListView组件的使用
    intellij idea设置(字体大小、背景)
  • 原文地址:https://www.cnblogs.com/zhangchengc919/p/5573502.html
Copyright © 2020-2023  润新知