hihoCoder 1389 Sewage Treatment 【二分+网络流+优化】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2016)网络赛)
#1389 : 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
题目链接:
http://hihocoder.com/problemset/problem/1389
题目大意:
N个污水厂fac,M个污水处理厂pku(N,M<=100)。每个污水厂坐标(xi,yi),会产生Si的污水。每个污水处理厂坐标(xi,yi),可以处理距离在C范围内的总量为U的污水(一个污水厂能被多个处理厂一起处理)。
所有污水处理厂的U,C必须保持相同,求在能处理所有污水的情况下 f=U*√C 函数最小值。(U为正整数,C为欧拉距离,坐标范围在[-10000,10000])
题目思路:
【二分+网络流+优化】
首先求出每个污水处理厂b[i].from到每个污水厂b[i].to的欧拉距离b[i].dis,从小到大排序,总共N*M条边。设源S 汇T
枚举C=b[i].dis(确保每个污水厂都和至少一个污水处理厂相连),二分需要的最小的U
check时将前i条边都加入到网络流的图中,边的容量为无穷大。S到每个污水处理厂连一条容量为U的边,每个污水厂到T连一条容量为Si的边
然后从S到T跑最大流看是否等于总污水量sum。等于就表明当前U可行,否则当前U不可行。
光这样做会T,需要优化,二分U的上界为当前可行的最小的U(因为C在不断增大,f只有在U减小的情况下才可能更优),下界为sum/n,表示每个污水处理厂至少处理的均摊量。
再加一个优化 当前枚举的C和二分下界l算出的函数f已经超过f的最优值时就break(再往后答案不会更优)。
【我也不知道为什么这样就过了。比赛的时候觉得会T就没写。。结果看了大牛的题解发现真的是这么做。不过比赛的时候优化没想清楚可能还会T】
//
//by coolxxx
//#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<iomanip>
#include<map>
#include<stack>
#include<queue>
#include<set>
#include<bitset>
#include<memory.h>
#include<time.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//#include<stdbool.h>
#include<math.h>
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define abs(a) ((a)>0?(a):(-(a)))
#define lowbit(a) (a&(-a))
#define sqr(a) ((a)*(a))
#define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b))
#define mem(a,b) memset(a,b,sizeof(a))
#define eps (1e-10)
#define J 10000
#define mod 1000000007
#define MAX 0x7f7f7f7f
#define PI 3.14159265358979323
#pragma comment(linker,"/STACK:1024000000,1024000000")
#define N 204
#define M 20004
using namespace std;
typedef long long LL;
double anss;
LL aans,sum;
int cas,cass;
int n,m,lll,ans;
int C,U,S,T,nn;
int d[N],vd[N],last[N];
int mapp[N][N];
bool mark[N];
struct Point
{
int x,y,qq;
}fac[N],pku[N];
struct Edge
{
int from,to,dis;
}b[M];
struct xxx
{
int from,to,next,q;
}a[M<<];
bool cmp1(Point aa,Point bb)
{
if(aa.x!=bb.x)return aa.x<bb.x;
return aa.y<bb.y;
}
bool cmp2(Edge aa,Edge bb)
{
return aa.dis<bb.dis;
}
void add(int x,int y,int z)
{
a[++lll].to=y;
a[lll].q=z;
a[lll].next=last[x];
last[x]=lll;
}
int sap(int u,int f)
{
int i,v,tt,asp=,mix=nn-;
if(u==T)return f;
for(i=last[u];i!=;i=a[i].next)
{
v=a[i].to;
if(a[i].q>)
{
if(d[u]==d[v]+)
{
tt=sap(v,min(f-asp,a[i].q));
asp+=tt;
a[i].q-=tt;
a[i^].q+=tt;
if(asp==f || d[S]==nn)
return asp;
}
mix=min(mix,d[v]);
}
}
if(asp!=)return asp;
if(!--vd[d[u]])d[S]=nn;
else vd[d[u]=mix+]++;
return asp;
}
bool check(int u)
{
int i,f;
mem(d,);mem(vd,);
nn=T;
vd[]=nn;
ans=;
while(d[S]<nn)
{
f=sap(S,MAX);
ans+=f;
}
if(ans==sum)return ;
return ;
}
void build(int k,int uu)
{
int i;
mem(last,);lll=;
for(i=;i<=m;i++)
add(S,i,uu),add(i,S,);
for(i=;i<=n;i++)
add(m+i,T,fac[i].qq),add(T,m+i,);
for(i=;i<=k;i++)
add(b[i].from,b[i].to+m,MAX),add(b[i].to+m,b[i].from,);
}
int main()
{
#ifndef ONLINE_JUDGEW
// freopen("1.txt","r",stdin);
// freopen("2.txt","w",stdout);
#endif
int i,j,k;
int x,y,z,l,r,mid;
// init();
// for(scanf("%d",&cass);cass;cass--)
// for(scanf("%d",&cas),cass=1;cass<=cas;cass++)
// while(~scanf("%s",s))
while(~scanf("%d%d",&n,&m))
{
sum=;cas=;anss=1e30;ans=;
mem(mark,);
if(!n && !m)break;
for(i=;i<=n;i++)
{
scanf("%d%d%d",&fac[i].x,&fac[i].y,&fac[i].qq);
sum+=fac[i].qq;
}
for(i=;i<=m;i++)
scanf("%d%d",&pku[i].x,&pku[i].y);
//sort(fac+1,fac+1+n,cmp1);
//sort(pku+1,pku+1+m,cmp1);
for(i=;i<=m;i++)
{
for(j=;j<=n;j++)
{
b[++cas].from=i;
b[cas].to=j;
b[cas].dis=sqr(fac[j].x-pku[i].x)+sqr(fac[j].y-pku[i].y);
}
}
sort(b+,b++cas,cmp2);
S=n+m+,T=n+m+;
for(j=,k=;k<=cas;k++)
{
if(!mark[b[k].to])
{
j++,mark[b[k].to]=;
if(j==n)break;
}
}
U=sum;
for(;k<=cas;k++)
{
C=b[k].dis;
l=sum/n,r=U;
if((double)l*sqrt(sqrt(C))>anss)break;
while(l<r)
{
mid=(l+r)>>;
build(k,mid);
if(check(mid))r=mid;
else l=mid+;
}
U=min(U,r);
anss=min(anss,U*sqrt(sqrt(C)));
}
printf("%d\n",int(anss+0.5));
}
return ;
}
/*
// //
*/
hihoCoder 1389 Sewage Treatment 【二分+网络流+优化】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2016)网络赛)的更多相关文章
- hihoCoder 1391 Countries 【预处理+排序+堆】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2016)网络赛)
#1391 : Countries 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 There are two antagonistic countries, countr ...
- hihoCoder 1392 War Chess 【模拟】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2016)网络赛)
#1392 : War Chess 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 Rainbow loves to play kinds of War Chess gam ...
- hihoCoder 1582 Territorial Dispute 【凸包】(ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛)
#1582 : Territorial Dispute 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 In 2333, the C++ Empire and the Ja ...
- hihoCoder 1584 Bounce 【数学规律】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛)
#1584 : Bounce 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 For Argo, it is very interesting watching a cir ...
- hihoCoder 1578 Visiting Peking University 【贪心】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛)
#1578 : Visiting Peking University 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 Ming is going to travel for ...
- hihoCoder 1586 Minimum 【线段树】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛)
#1586 : Minimum 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 You are given a list of integers a0, a1, …, a2 ...
- hihocoder 1586 ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛-题目9 : Minimum【线段树】
https://hihocoder.com/problemset/problem/1586 线段树操作,原来题并不难..... 当时忽略了一个重要问题,就是ax*ay要最小时,x.y可以相等,那就简单 ...
- 【分类讨论】【计算几何】【凸包】hihocoder 1582 ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛 E. Territorial Dispute
题意:平面上n个点,问你是否存在一种黑白染色方案,使得对于该方案,无法使用一条直线使得黑色点划分在直线一侧,白色点划分在另一侧.如果存在,输出一种方案. 如果n<=2,显然不存在. 如果所有点共 ...
- 【线段树】hihocoder 1586 ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛 I. Minimum
题意:给你一个序列(长度不超过2^17),支持两种操作:单点修改:询问区间中最小的ai*aj是多少(i可以等于j). 只需要线段树维护区间最小值和最大值,如果最小值大于等于0,那答案就是minv*mi ...
随机推荐
- TFS 服务器更换后工作区无法绑定
需要删除工作区,删除命令如下 tf workspace /delete 工作区名;创建的用户 /server:TFS服务器 例 tf workspace /delete WHQ-PC;whq /ser ...
- 数据挖掘经典书籍[ZZ]
数据挖掘就是在数据库中查找所需数据的过程,它是随着数据库产生的一门学科.近几年,数据库的发展还是非常迅速的,数据挖掘也成为热门技术,学习的人络绎不绝.下面给大家介绍的就是数据挖掘经典书籍及数据挖掘书籍 ...
- c++primerplus(第六版)编程题——第3章(数据类型)
声明:作者为了调试方便,每一章的程序写在一个工程文件中,每一道编程练习题新建一个独立文件,在主函数中调用,我建议同我一样的初学者可以采用这种方式,调试起来会比较方便. 工程命名和文件命名可以命名成易识 ...
- SGU 183.Painting the balls
时间限制:0.25s 空间限制:4M 题意: 在n(n<=10000)个球中,给若干个球涂色,每个球涂色的代价为Ci,使得任意连续m(m<=100)个球中有至少两个球被涂了色. Solu ...
- PHP+MySQL中对UTF-8,UTF8(utf8),set names gbk 的理解
问题一:在我们进行数据库操作时会发现,数据库中表的编码用的是utf-8,但是在进行dos命令是要使用set names gbk (一)Mysql中默认字符集设置有四级:服务器级,数据库级,表级,和字段 ...
- 除法(Division ,UVA 725)-ACM集训
参考:http://www.cnblogs.com/xiaobaibuhei/p/3301110.html 算法学到很弱,连这么简单个问题都难到我了.但我偏不信这个邪,终于做出来了.不过,是参照别人的 ...
- MBR
Mbr位于磁盘的0柱面,0磁头,1扇区. MBR 有三部分构成,主引导程序,硬盘分区表DPT和,硬盘的有效标志55AA.在512个字节的主引导扇区里. 主引导程序占446个字节,dpt占6 ...
- IPython学习笔记
IPython 前言 Life is short, you need Python 最近开始学习数据挖掘,需要使用到Python,其实大学时代就有接触过Python,但是却始终没有系统的进行学习过. ...
- Django框架学习-Model进阶用法
Model进阶用法 回顾 访问外键 访问多对多关系 更改数据库结构 当处理数据库结构改变时,需要注意到几点: 增加字段 首先在开发环境中: 再到产品环境中: 删除字段 删除多对多字段 删除model ...
- 使用ToUpperInvariant避免使用ToUpper
ToUpperInvariant使用不依赖于区域性进行转换,而ToUpper则使用了当前线程的CultureInfo,进行转换,所以性能会有所影响,以下为测试: [Test] public void ...

