zoukankan      html  css  js  c++  java
  • IndiaHacks 2016

    D. Delivery Bears

    题目连接:

    http://www.codeforces.com/contest/653/problem/D

    Description

    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 n nodes 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 n, m 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 ai, bi and ci (1 ≤ ai, bi ≤ n, ai ≠ bi, 1 ≤ 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 .

    Sample Input

    4 4 3
    1 2 2
    2 4 1
    1 3 1
    3 4 2

    Sample Output

    1.5000000000

    Hint

    题意

    给一个图,每个边有边权,然后有x只熊,每个熊都要背负一样重量的货物,每头熊通过一条路径到i,每条边被所有熊经过的次数乘于货物重量不能大于边权,然后问你最大的货物总重量是多少

    每只熊都必须要用,每个熊背负的货物重量一致,所以等价于求每只熊背负的货物的最大重量

    题解:

    比较显然的是二分+最大流

    然后每条边的cap就是该边的边权除以你二分的答案值。

    然后跑一发最大流check是否满流就好了。

    现在有一个问题就是cap会爆int,其实这时候只用和x取个min就好了。

    代码

     #include<bits/stdc++.h>
    using namespace std;
    
    const int MAXN=100000,MAXM=100000,inf=1e9;
    struct Edge
    {
        int v,c,f,nx;
        Edge() {}
        Edge(int v,int c,int f,int nx):v(v),c(c),f(f),nx(nx) {}
    } E[MAXM];
    int G[MAXN],cur[MAXN],pre[MAXN],dis[MAXN],gap[MAXN],N,sz;
    void init(int _n)
    {
        N=_n,sz=0; memset(G,-1,sizeof(G[0])*N);
    }
    void link(int u,int v,int c)
    {
        E[sz]=Edge(v,c,0,G[u]); G[u]=sz++;
        E[sz]=Edge(u,0,0,G[v]); G[v]=sz++;
    }
    
    bool bfs(int S,int T)
    {
        static int Q[MAXN]; memset(dis,-1,sizeof(dis[0])*N);
        dis[S]=0; Q[0]=S;
        for (int h=0,t=1,u,v,it;h<t;++h)
        {
            for (u=Q[h],it=G[u];~it;it=E[it].nx)
            {
                if (dis[v=E[it].v]==-1&&E[it].c>E[it].f)
                {
                    dis[v]=dis[u]+1; Q[t++]=v;
                }
            }
        }
        return dis[T]!=-1;
    }
    int dfs(int u,int T,int low)
    {
        if (u==T) return low;
        int ret=0,tmp,v;
        for (int &it=cur[u];~it&&ret<low;it=E[it].nx)
        {
            if (dis[v=E[it].v]==dis[u]+1&&E[it].c>E[it].f)
            {
                if (tmp=dfs(v,T,min(low-ret,E[it].c-E[it].f)))
                {
                    ret+=tmp; E[it].f+=tmp; E[it^1].f-=tmp;
                }
            }
        }
        if (!ret) dis[u]=-1; return ret;
    }
    int dinic(int S,int T)
    {
        int maxflow=0,tmp;
        while (bfs(S,T))
        {
            memcpy(cur,G,sizeof(G[0])*N);
            while (tmp=dfs(S,T,inf)) maxflow+=tmp;
        }
        return maxflow;
    }
    int x[600],y[600],z[600];
    int n,m,X;
    bool check(double ad)
    {
        init(5000);
        for(int i=1;i<=m;i++)
            link(x[i],y[i],min(1.0*X,z[i]/(ad)));
        link(0,1,X);
        link(n,n+1,X);
        if(dinic(0,n+1)==X)return true;
        return false;
    }
    int main()
    {
    
        scanf("%d%d%d",&n,&m,&X);
        for(int i=1;i<=m;i++)
            scanf("%d%d%d",&x[i],&y[i],&z[i]);
        double l=0,r=1e9,ans=0;
        for(int i=0;i<70;i++)
        {
            double mid = (l+r)/2.0;
            if(check(mid))l=mid,ans=mid;
            else r=mid;
        }
        printf("%.12f
    ",ans*X);
    }
  • 相关阅读:
    LeetCode with Python -> Linked List
    拼多多2018校招编程题汇总 Python实现
    Windows命令行中pip install jieba,但没有安装到anaconda3中
    sklearn快速入门
    人工神经网络在肺结核诊断中应用的研究进展
    Leetcode with Python -> Array
    标签语义空间生成
    leetcode with python -> tree
    读书笔记——中文信息处理发展报告(2016)
    移动开发学习记录
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5296536.html
Copyright © 2011-2022 走看看