zoukankan      html  css  js  c++  java
  • hihocoder-1389&&2016北京网赛07 Sewage Treatment(二分+网络流)

    题目链接:

    Sewage Treatment

    时间限制:2000ms
    单点时限:2000ms
    内存限制:256MB

    描述

    After years of suffering, people could not tolerate the pollution in the city any more, and started a long-lasting protest. Eventually, the municipal government made up its mind to deal with the sewage discharged by factories. The government planned to deploy some Pollution-Killer Utilities (PKUs) in order to clean all the sewage, and meanwhile, minimize the total cost.

    The city can be approximately considered as a plane. There are n factories discharging sewage. The i-th one is located at (xi, yi), and discharges si units of sewage every day. The government has built m PKUs. The PKUs' locations are also fixed, and the j-th one is located at (xj, yj). Two features of PKUs are essential, and you will need to find the best choice of them: u is the upper limit of units of sewage that can be cleaned by one PKU every day, and c is the coverage radius of one PKU (which means, only if the distance between the PKU and the factory does not exceed the coverage radius, sewage discharged by this factory can be cleaned by this PKU). Note that all the PKUs share the same u and c. Because of some technical reasons, u has to be a positive integer.

    Here is your task. The cost of deploying these PKUs can be weighed by an empirical formula:

    f = u×sqrt(c)

    You need to calculate the minimum value of f, and guarantee all the sewage is treated.

    输入

    There are no more than 15 test cases. Each test case starts with a line containing two positive integers n and m (1 <= n, m <= 100), representing the number of factories and PKUs. Then n lines follow, the i-th line contains three integers xi, yi, si (-10000 <= xi, yi <= 10000, 1 <= si <= 100), representing the i-th factory's location and the quantity of sewage discharged by it every day. In the next following m lines, the j-th line contains two integers xj, yj (-10000 <= xj, yj <= 10000), representing the j-th PKU's location. After each test case there is an empty line. After all the test cases there is a line "0 0", which indicates the end of the input, and should not be processed.

    输出

    For each test case, output a single line containing a number, which is the minimum value of f. This number should be rounded to an integer.

    提示

    Test case 1:

    When u = 12 and c = 2, f has the minimum value of 12 * sqrt(2) = 16.97 = 17.

    Test case 2:

    When u = 10, c = sqrt(2), f has the minimum value of 10 * sqrt(sqrt(2)) = 11.89 = 12.

    The input guarantees that there is always a valid solution. You may assume that the factories and PKUs are uniformly randomly distributed on the plane.

    样例输入
    3 1
    -1 0 5
    2 0 3
    0 1 4
    0 0
    
    4 2
    0 0 4
    3 0 5
    3 2 3
    0 2 6
    1 1
    2 1
    
    0 0
    样例输出
    17
    12


    题意:

    给出n个工厂,每个工厂的坐标和每天产生的污水量,再给m个pku,现在要求f=u*sqrt(r)的最小值,要求所有的污水都处理完;
    只有工厂的与pku的距离<=r时这个工厂的污水才能给pku处理,而且给的量是任意的,而且所有的u和r是一样的;

    思路:

    枚举所有的距离,然后二分u,建图的时候源点s到所有的工厂连边,容量为每天产生的污水量,所有的pku到汇点连边,容量为u,然后相距<=r的pku与工厂连边,容量无穷;
    跑最大流看是否==sum;
    AC代码
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <bits/stdc++.h>
    #include <stack>
    #include <map>
      
    using namespace std;
      
    #define For(i,j,n) for(int i=j;i<=n;i++)
    #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 int inf=1e9;
    const int N=(1<<20)+10;
    const int maxn=205;
    const double eps=1e-12;
    
    struct Edge
    {
        int from,to,cap,flow;
    };
    vector<Edge>edge;
    vector<int>G[maxn];
    bool vis[maxn];
    int cur[maxn],n,m,fn,s,t,d[maxn];
    int dis[210][210];
    int x[maxn],y[maxn],fs[maxn],sum,lower,upper,cnt;
    double ans;
    struct po
    {
        int from,to,dis;
    }a[105*105];
    int cmp(po u,po v)
    {
        return u.dis<v.dis;
    }
    inline void add_edge(int from,int to,int cap)
    {
        edge.push_back((Edge){from,to,cap,0});
        edge.push_back((Edge){to,from,0,0});
        m=edge.size();
        G[from].push_back(m-2);
        G[to].push_back(m-1);
    }
    bool bfs()
    {
        mst(vis,0);
        queue<int>Q;
        Q.push(s);
        d[s]=0;
        vis[s]=1;
        while(!Q.empty())
        {
            int x=Q.front();Q.pop();
            int len=G[x].size();
            for(int i=0;i<len;i++)
            {
                Edge& e=edge[G[x][i]];
                if(!vis[e.to]&&e.cap>e.flow)
                {
                    vis[e.to]=1;
                    d[e.to]=d[x]+1;
                    Q.push(e.to);
                }
            }
        }
        return vis[t];
    }
    
    int dfs(int x,int a)
    {
        if(x==t||a==0)return a;
        int flow=0,f,len=G[x].size();
        for(int& i=cur[x];i<len;i++)
        {
            Edge& e=edge[G[x][i]];
            if(d[x]+1==d[e.to]&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0)
            {
                e.flow+=f;
                edge[G[x][i]^1].flow-=f;
                flow+=f;
                a-=f;
                if(a==0)break;
            }
        }
        return flow;
    }
    
    int maxflow()
    {
        int flow=0;
        while(bfs())
        {
            mst(cur,0);
            flow+=dfs(s,inf);
        }
        return flow;
    }
    inline void Init(int k,int hi)
    {
        edge.clear();
        for(int i=0;i<=t;i++)G[i].clear();
        for(int i=1;i<=k;i++)
        {
            add_edge(a[i].from,a[i].to,inf);
        }
        for(int i=k+1;i<=cnt;i++)
        {
            if(a[i].dis>a[k].dis)break;
            add_edge(a[i].from,a[i].to,inf);
        }
        for(int i=1;i<=n;i++)add_edge(s,i,fs[i]);
        for(int i=n+1;i<=n+fn;i++)add_edge(i,t,hi);
    }
    inline int check(int k,int flow)
    {
        Init(k,flow);
        int ans=maxflow();
        if(ans==sum)return 1;
        return 0;
    }
    double solve(int k)
    {
        double dist=sqrt(sqrt(a[k].dis*1.0));
        int l=lower,r=min(upper,(int)(ceil(ans/dist)));
        while(l<r)
        {
            int mid=(l+r)>>1;
            if(check(k,mid))r=mid;
            else l=mid+1;
        }
        upper=r;
        return dist*r;
    }
    int main()
    {
        while(1)
        {
            read(n);read(fn);
            if(!n&&!fn)break;
            sum=0;
            for(int i=1;i<=n;i++)
            {
                read(x[i]);read(y[i]);read(fs[i]);
                sum=sum+fs[i];
            }
            for(int i=n+1;i<=n+fn;i++)
            {
               read(x[i]);read(y[i]);
            }
            cnt=0;
            for(int i=1;i<=n;i++)
            {
                for(int j=n+1;j<=n+fn;j++)
                {
                    int dist=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
                    a[++cnt].from=i;
                    a[cnt].to=j;
                    a[cnt].dis=dist;
                }
            }
            sort(a+1,a+cnt+1,cmp);
            a[0].dis=-1;
            s=0,t=n+fn+1;
            ans=inf;
            lower=(sum+fn-1)/fn,upper=1e4;
            for(int i=1;i<=cnt;i++)
            {
                if(a[i].dis==a[i-1].dis)continue;
                double temp=solve(i);
                ans=min(temp,ans);
            }
            printf("%.0lf
    ",ans);
        }
        return 0;
    }
    

      



  • 相关阅读:
    java.lang.IllegalAccessError: tried to access method org.apache.poi.util.POILogger.log from class org.apache.poi.openxml4j.opc.ZipPackage
    相同域名不同端口的两个应用,cookie名字、路径都相同的情况下,后面cookie会覆盖前面cookie吗
    power designer 连接mysql提示“connection test failed”
    疑问:Spring 中构造器、init-method、@PostConstruct、afterPropertiesSet 孰先孰后,自动注入发生时间
    intelj idea 创建聚合项目(典型web项目,包括子项目util、dao、service)
    Mysql启动时提示:Another MySQL daemon already running with the same unix socket.
    MySql中的varchar长度究竟是字节还是字符
    百度echarts使用--y轴label数字太长难以全部显示
    记录项目中用的laypage分页代码
    Ubuntu16.04下安装Cmake-3.8.2并为其配置环境变量
  • 原文地址:https://www.cnblogs.com/zhangchengc919/p/5905873.html
Copyright © 2011-2022 走看看