HDU 5046 Airport DLX
来源:互联网 发布:qq刷钻软件下载 编辑:程序博客网 时间:2024/06/05 12:02
【题目大意】
有n个城市,你可以从中选k个城市建立飞机场。建好飞机场后,城市i(1<=i<=n)距离最近的飞机场有一个距离值di。你的任务是选择一个建造方式,使得max(di)最小,输出这个最小值。
【思路】
基本是hdu 3656的原题,和hdu 4398也很像。
我们可以二分最小的距离值。如果城市i建立飞机场,存在城市j,满足两城市的距离<=二分的值。令mat[i][j] = 1,否则mat[i][j] = 0。这个表,就是精确覆盖的表,只不过这里允许重复覆盖。。。非精确覆盖问题,直接贴模板。。。
//#pragma comment(linker, "/STACK:102400000,102400000")#include<cstdio>#include<cstring>#include<vector>#include<queue>#include<cmath>#include<cctype>#include<string>#include<algorithm>#include<iostream>#include<ctime>#include<map>#include<set>using namespace std;#define MP(x,y) make_pair((x),(y))#define PB(x) push_back(x)typedef __int64 LL;//typedef unsigned __int64 ULL;/* ****************** */const int INF=100011122;const double INFF=1e100;const double eps=1e-8;//const LL mod=1000000007;const int NN=100010;const int MM=2000010;/* ****************** */const int maxn=61;const int maxr=61;const int maxnode=3700;int sz,ansd;int S[maxn],H[maxr];int row[maxnode],col[maxnode];int L[maxnode],D[maxnode],U[maxnode],R[maxnode];bool mat[61][61];bool vis[61];LL dis[61][61];LL x[61], y[61];LL tf[4000];int kk;void dl_init(int n){ memset(H,-1,sizeof(H)); int i; for(i=0;i<=n;i++) { U[i]=D[i]=i; L[i]=i-1; R[i]=i+1; S[i]=0; } L[0]=n; R[n]=0; sz=n+1;}void dl_add(int r,int c){ row[sz]=r,col[sz]=c; S[c]++; U[sz]=U[c]; D[sz]=c; D[ U[c] ]=sz; U[c]=sz; if(H[r]==-1) { H[r]=L[sz]=R[sz]=sz; } else { L[sz]=L[H[r]]; R[sz]=H[r]; R[ L[sz] ]=sz; L[ H[r] ]=sz; } sz++;}void remove(int id){ int i; for(i=D[id];i!=id;i=D[i]) { L[R[i]]=L[i]; R[L[i]]=R[i]; }}void restore(int id){ int i; for(i=U[id];i!=id;i=U[i]) { R[L[i]]=i; L[R[i]]=i; }}int h(){ int i,j,k,ans=0; memset(vis,false,sizeof(vis)); for(i=R[0];i!=0;i=R[i]) { if(!vis[i]) { ans++; vis[i]=true; for(j=D[i];j!=i;j=D[j]) for(k=R[j];k!=j;k=R[k]) vis[ col[k] ]=true; } } return ans;}void dl_dfs(int d){ if(ansd <= kk) return; if(d+h() > kk) return; if(R[0]==0) { ansd=d; return; } int i,j,c=R[0]; for(i=R[0];i!=0;i=R[i]) if(S[i]<S[c]) c=i; for(i=D[c];i!=c;i=D[i]) { remove(i); for(j=R[i];j!=i;j=R[j]) remove(j); dl_dfs(d+1); for(j=L[i];j!=i;j=L[j]) restore(j); restore(i); }}int goo(int n,LL dd){ int i,j; for(i = 1; i <= n; i ++) { for(j = 1; j <= n; j++) { if(dis[i][j] <= dd) mat[i][j] = true; else mat[i][j] = false; } } dl_init(n); for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { if(mat[i][j] || i==j) { dl_add(i,j); } } } ansd=n; dl_dfs(0); return ansd;}LL f_abs(LL x){ if(x >= 0)return x; return -x;}int main(){ int cas, ee = 0; int n, k, i, j, tol, m; int l ,r, mid; scanf("%d", &cas); while(cas--) { scanf("%d%d", &n, &k); kk = k; for(i = 1; i <= n; i ++) { scanf("%I64d%I64d",&x[i],&y[i]); } tol = 0; for(i = 1; i <= n; i ++) for(j = 1; j <= n; j ++) { dis[i][j] = f_abs(x[i]-x[j]) + f_abs(y[i]-y[j]); tf[++tol] = dis[i][j]; } sort(tf+1,tf+1+tol); m = unique(tf+1,tf+1+tol) - tf - 1; tf[0] = -1; l = 0; r = m; while(l + 1 < r) { mid = (l + r)>>1; if(goo(n, tf[mid]) <= k) r = mid; else l = mid; } printf("Case #%d: ", ++ee); printf("%I64d\n",tf[r]); } return 0;}
0 0
- HDU 5046 Airport DLX
- HDU 5046 Airport [DLX] [RepeatCover]
- HDU 5046 Airport(DLX重复覆盖)
- hdu 5046 airport DLX可重复覆盖
- HDU 5046 Airport【DLX重复覆盖】
- HDU 5046 Airport DLX多重覆盖
- HDU-5046 Airport(二分+DLX重复覆盖)
- HDU 5046 ( Airport ) DLX模板题,手残again
- HDU 5046 Airport (DLX可重复覆盖+二分)
- HDU 5046 Airport(二分+DLX重复覆盖)
- HDU 5046 Airport DLX 2014 ACM/ICPC Asia Regional Shanghai Online
- 【HDU5046】【DLX】Airport
- HDU 5046 Airport
- hdu 5046 Airport
- HDU 5046 Airport
- HDU 5046 Airport
- HDU 5046 DLX
- DLX重复覆盖 hdu5046 Airport
- UVALive 6175 Maximum Random Walk 期望+概率dp
- 在菜单Setting加入子菜单
- Hdu-5050 Divided Land(Java高精度)
- UVALive 6176 Faulhaber's Triangle C++大数模拟
- activity切换动画效果
- HDU 5046 Airport DLX
- 安卓内部下载
- 使用Xcode 5创建(静态库)--Good
- Activity绑定service
- Java虚拟机工作原理详解
- IntentService
- [WHY] 一些编程相关的分享
- 单向链表逆置的功能实现
- Hdu-5053 the Sum of Cube(水题)