Fire station

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 1308    Accepted Submission(s): 434

Problem Description
A city's map can be seen as a two dimensional plane. There are N houses in the city and these houses can be seen as N points P1 …… PN on the two dimensional plane. For simplicity's sake, assume that the time
spent from one house number to another is equal to the distance between two points corresponding to the house numbers. The government decides to build M fire stations from N houses. (If a station is build in Pi, We can think the station is next to the house
and the time from the station to the house is considered zero.) It is obvious that if some place such as Pi is breaking out of fire, the nearest station will dispatched a fire engine quickly rushed to the rescue scene. The time it takes from this station to
the rescue scene is called rescue time. Now you need to consider about a problem that how to choice the positions of the M fire station to minimize the max rescue time of all the houses.
 
Input
The fi rst line of the input contains one integer T, where T is the number of cases. For each case, the fi rst line of each case contains two integers N and M separated by spaces (1 ≤ M ≤N ≤ 50), where N is the number of houses and
M is the number of fire stations. Then N lines is following. The ith line contains two integers Xi and Yi (0 ≤ Xi, Yi ≤ 10000), which stands for the coordinate of the ith house.
 
Output
The rescue time which makes the max rescue time is minimum.
 
Sample Input
2
4 2
1 1
1 2
2 3
2 4
4 1
1 1
1 2
2 3
2 4
 
Sample Output
1.000000
2.236068
 给定n个城市。要修建m个防火站,使得每个城市发生火灾所须要的最大救援时间最短。

一開始二分距离,然后枚举建边,dlx判定tle。学习别人的写法。把两点间距离的序列排序,二分下标,这样时效高了非常多。

距离序列第二重循环仅仅枚举一半wa,所有枚举ac,非常不理解。

代码:

/* ***********************************************
Author :_rabbit
Created Time :2014/4/28 14:08:33
File Name :1.cpp
************************************************ */
#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <string>
#include <time.h>
#include <math.h>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define eps 1e-8
#define pi acos(-1.0)
typedef long long ll;
struct Point{
double x,y;
}city[600];
double dis[600][600],dd[500100];
double dist(Point a,Point b){
double s=a.x-b.x,t=a.y-b.y;
return sqrt(s*s+t*t);
}
struct DLX{
const static int maxn=311110;
#define FF(i,A,s) for(int i = A[s];i != s;i = A[i])
int L[maxn],R[maxn],U[maxn],D[maxn];
int size,col[maxn],row[maxn],s[maxn],H[maxn];
bool vis[700];
int ans[maxn],cnt;
void init(int m){
for(int i=0;i<=m;i++){
L[i]=i-1;R[i]=i+1;U[i]=D[i]=i;s[i]=0;
}
memset(H,-1,sizeof(H));
L[0]=m;R[m]=0;size=m+1;
}
void link(int r,int c){
U[size]=c;D[size]=D[c];U[D[c]]=size;D[c]=size;
if(H[r]<0)H[r]=L[size]=R[size]=size;
else {
L[size]=H[r];R[size]=R[H[r]];
L[R[H[r]]]=size;R[H[r]]=size;
}
s[c]++;col[size]=c;row[size]=r;size++;
}
void del(int c){//精确覆盖
L[R[c]]=L[c];R[L[c]]=R[c];
FF(i,D,c)FF(j,R,i)U[D[j]]=U[j],D[U[j]]=D[j],--s[col[j]];
}
void add(int c){ //精确覆盖
R[L[c]]=L[R[c]]=c;
FF(i,U,c)FF(j,L,i)++s[col[U[D[j]]=D[U[j]]=j]];
}
bool dfs(int k){//精确覆盖
if(!R[0]){
cnt=k;return 1;
}
int c=R[0];FF(i,R,0)if(s[c]>s[i])c=i;
del(c);
FF(i,D,c){
FF(j,R,i)del(col[j]);
ans[k]=row[i];if(dfs(k+1))return true;
FF(j,L,i)add(col[j]);
}
add(c);
return 0;
}
void remove(int c){//反复覆盖
FF(i,D,c)L[R[i]]=L[i],R[L[i]]=R[i];
}
void resume(int c){//反复覆盖
FF(i,U,c)L[R[i]]=R[L[i]]=i;
}
int A(){//估价函数
int res=0;
memset(vis,0,sizeof(vis));
FF(i,R,0)if(!vis[i]){
res++;vis[i]=1;
FF(j,D,i)FF(k,R,j)vis[col[k]]=1;
}
return res;
}
void dfs(int now,int &lim){//反复覆盖
if(R[0]==0)cnt=now,lim=min(lim,now);
else if(now+A()<lim){
int temp=INF,c;
FF(i,R,0)if(temp>=s[i])temp=s[i],c=i;
FF(i,D,c){
ans[now]=i;
remove(i);FF(j,R,i)remove(j);
dfs(now+1,lim);
FF(j,L,i)resume(j);resume(i);
}
}
}
}dlx;
int main()
{
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
int T,n,m;
cin>>T;
while(T--){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%lf%lf",&city[i].x,&city[i].y);
int pp=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
dis[i][j]=dist(city[i],city[j]);
dd[pp++]=dis[i][j];
}
sort(dd,dd+pp);
int left=0,right=pp-1;
while(left<right){
int mid=(left+right)/2;
dlx.init(n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(dis[i][j]<=dd[mid])dlx.link(i,j);
int ans=INF;
dlx.dfs(0,ans);
if(ans>m)left=mid+1;
else right=mid;
}
printf("%.6lf\n",dd[left]);
}
return 0;
}

HDU 3656 二分+dlx判定的更多相关文章

  1. hdu 5046 二分+DLX模板

    http://acm.hdu.edu.cn/showproblem.php?pid=5046 n城市建k机场使得,是每个城市最近机场的距离的最大值最小化 二分+DLX 模板题 #include < ...

  2. hdu 3622 二分+2-SAT判定

    思路:如题 #include<iostream> #include<algorithm> #include<cstring> #include<cstdio& ...

  3. HDU 5046 Airport(dlx)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5046 题意:n个城市修建m个机场,使得每个城市到最近进场的最大值最小. 思路:二分+dlx搜索判定. ...

  4. hdu 4024 二分

    转自:http://www.cnblogs.com/kuangbin/archive/2012/08/23/2653003.html   一种是直接根据公式计算的,另外一种是二分算出来的.两种方法速度 ...

  5. [NOIP 2010] 关押罪犯 (二分+二分图判定 || 并查集)

    题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值"( ...

  6. HDU 3586 二分答案+树形DP判定

    HDU 3586 『Link』HDU 3586 『Type』二分答案+树形DP判定 ✡Problem: 给定n个敌方据点,1为司令部,其他点各有一条边相连构成一棵树,每条边都有一个权值cost表示破坏 ...

  7. hdu 3656 DLX

    思路:二分枚举建边,用DLX判断是否满足. #include<set> #include<cmath> #include<queue> #include<cs ...

  8. [DLX反复覆盖] hdu 3656 Fire station

    题意: N个点.再点上建M个消防站. 问消防站到每一个点的最大距离的最小是多少. 思路: DLX直接二分推断TLE了. 这时候一个非常巧妙的思路 我们求的距离一定是两个点之间的距离 因此我们把距离都求 ...

  9. HDU 2295 Radar (DLX + 二分)

    Radar Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

随机推荐

  1. Ubuntu 系统的常用快捷键

    Ubuntu操作基本快捷键 ibus-setup :设置系统输入法 scp filename username@serverIp:/home/xxx/xxx/filename   回车输入该usern ...

  2. 从如何停掉 Promise 链说起

    在使用Promise处理一些复杂逻辑的过程中,我们有时候会想要在发生某种错误后就停止执行Promise链后面所有的代码. 然而Promise本身并没有提供这样的功能,一个操作,要么成功,要么失败,要么 ...

  3. Java_Web三大框架之Hibernate+jsp+selvect+HQL登入验证

    刚开始接触Hibernate有些举手无措,觉得配置信息太多.经过一个星期的适应,Hibernate比sql简单方便多了.下面做一下Hibernate+jsp+selvect+HQL登入验证. 第一步: ...

  4. THREE.js代码备份——canvas - geometry - earth(球体贴纹理)

    <!DOCTYPE html> <html lang="en"> <head> <title>three.js canvas - g ...

  5. Self-Attetion

    四.self-attention 1.是什么? attention机制通常用在encode与decode之间,但是self-attention则是输入序列与输出序列相同,寻找序列内部元素的关系即 K= ...

  6. 【剑指Offer】剑指offer题目汇总

      本文为<剑指Offer>刷题笔记的总结篇,花了两个多月的时间,将牛客网上<剑指Offer>的66道题刷了一遍,以博客的形式整理了一遍,这66道题属于相对基础的算法题目,对于 ...

  7. JavaScript day4(条件语句和条件运算符)

    1. 布尔值 布尔值要么是 true 要么是 false .它非常像电路开关, true 是“开”,false 是“关”.这两种状态是互斥的. 2. if 语句 if 语句用于在代码中做条件判断.关键 ...

  8. Dinic当前弧优化 模板及教程

    在阅读本文前,建议先自学最大流的Ek算法. 引入 Ek的核心是执行bfs,一旦找到增广路就停下来进行增广.换言之,执行一遍BFS执行一遍DFS,这使得效率大大降低.于是我们可以考虑优化. 核心思路 在 ...

  9. [luogu2594 ZJOI2009]染色游戏(博弈论)

    传送门 Solution 对于硬币问题,结论是:当前局面的SG值等于所有背面朝上的单个硬币SG值的异或和 对于求单个背面朝上的硬币SG值...打表找规律吧 Code //By Menteur_Hxy ...

  10. 小白两篇博客熟练操作MySQL 之 第一篇

    小白两篇博客熟悉操作MySQL  之   第一篇 一.概述 1. 什么是数据库? 答: 储存数据的仓库, 如: 在ATM的事例中创建的一个db 目录, 称为数据库 2. 什么是Mysql, Oracl ...