HDU 3656 Fire station
来源:互联网 发布:c语言文件名 编辑:程序博客网 时间:2024/06/05 03:33
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
24 21 11 22 32 44 11 11 22 32 4
Sample Output
1.0000002.236068
dlx重复覆盖+二分距离
#include<cstdio>#include<vector>#include<cmath>#include<map>#include<cstring>#include<algorithm>using namespace std;typedef long long ll;const ll maxn = 105;int T, n, m, x, y, t, tot, X[maxn], Y[maxn], l, r, mid;double mp[maxn][maxn], dis[maxn*maxn];inline void read(int &ret){char c;do {c = getchar();} while (c < '0' || c > '9');ret = c - '0';while ((c = getchar()) >= '0' && c <= '9')ret = ret * 10 + (c - '0');}struct DLX{#define maxn 500005#define F(i,A,s) for (int i=A[s];i!=s;i=A[i])int L[maxn], R[maxn], U[maxn], D[maxn];int row[maxn], col[maxn], ans[maxn], cnt[maxn];int n, m, num, sz;void add(int now, int l, int r, int u, int d, int x, int y){L[now] = l;R[now] = r;U[now] = u;D[now] = d; row[now] = x; col[now] = y;}void reset(int n, int m){num = 0x7FFFFFFF;this->n = n;this->m = m;for (int i = 0; i <= m; i++){add(i, i - 1, i + 1, i, i, 0, i);cnt[i] = 0;}L[0] = m; R[m] = 0; sz = m + 1;}void insert(int x, int y){int ft = sz - 1;if (row[ft] != x){add(sz, sz, sz, U[y], y, x, y);U[D[sz]] = sz; D[U[sz]] = sz;}else{add(sz, ft, R[ft], U[y], y, x, y);R[L[sz]] = sz; L[R[sz]] = sz;U[D[sz]] = sz; D[U[sz]] = sz;}++cnt[y];++sz;}//精确覆盖void remove(int now){R[L[now]] = R[now];L[R[now]] = L[now];F(i, D, now) F(j, R, i){D[U[j]] = D[j];U[D[j]] = U[j];--cnt[col[j]];}}void resume(int now){F(i, U, now)F(j, L, i){D[U[j]] = j;U[D[j]] = j;++cnt[col[j]];}R[L[now]] = now;L[R[now]] = now;}bool dfs(int x){//if (x + A() >= num) return;if (!R[0]) { num = min(num, x); return true; }int now = R[0];F(i, R, 0) if (cnt[now]>cnt[i]) now = i;remove(now);F(i, D, now){ans[x] = row[i];F(j, R, i) remove(col[j]);if (dfs(x + 1)) return true;F(j, L, i) resume(col[j]);}resume(now);return false;}//精确覆盖//重复覆盖void Remove(int now){F(i, D, now){L[R[i]] = L[i];R[L[i]] = R[i];}}void Resume(int now){F(i, U, now) L[R[i]] = R[L[i]] = i;}int vis[maxn];int flag[maxn];int A(){int dis = 0;F(i, R, 0) vis[i] = 0;F(i, R, 0) if (!vis[i]){dis++;vis[i] = 1;F(j, D, i) F(k, R, j) vis[col[k]] = 1;}return dis;}void Dfs(int x){if (!R[0]) num = min(num, x);else if (x + A()<num){int now = R[0];F(i, R, 0) if (cnt[now]>cnt[i]) now = i;F(i, D, now){Remove(i); F(j, R, i) Remove(j);Dfs(x + 1);F(j, L, i) Resume(j); Resume(i);}}}//重复覆盖}dlx;int main(){read(T);while (T--){scanf("%d%d", &n, &m);for (int i = 1; i <= n; i++) scanf("%d%d", &X[i], &Y[i]);tot = 0;for (int i = 1; i <= n;i++)for (int j = 1; j <= n; j++){mp[i][j] = sqrt((X[i] - X[j])*(X[i] - X[j]) + (Y[i] - Y[j])*(Y[i] - Y[j]));if (i < j || (i == j&&i == 1)) dis[tot++] = mp[i][j];}sort(dis, dis + tot);r = unique(dis, dis + tot) - dis - 1;for (l = 0; l < r;){mid = (l + r) >> 1;dlx.reset(n, n);for (int i = 1; i <= n; i++)for (int j = 1; j <= n; j++)if (dis[mid] >= mp[i][j]) dlx.insert(i, j);dlx.Dfs(0);if (dlx.num > m) l = mid + 1; else r = mid;}printf("%.6lf\n", dis[l]);}return 0;}
0 0
- HDU 3656 Fire station
- [DLX重复覆盖] hdu 3656 Fire station
- HDU 3656 Fire station DLX多重覆盖
- Fire Station
- Fire Station
- HDU 3656 Fire station(巧妙的二分+DLX重复覆盖)
- POJ 2607 Fire Station
- poj 2607 Fire Station
- poj2607 Fire Station
- poj 2607 Fire Station
- POJ 2607 Fire Station
- ZOJ1857 Fire Station
- UVa 10278 - Fire Station
- poj 2607 Fire Station
- NYOJ 210 Fire Station
- HDU3656-Fire station
- HDU3656 Fire Station Dancing Links
- poj 2607 Fire Station(floyd)
- Paper Reading: Deep Multimodal Speaker Naming
- HDU 1856 More is better
- 7_29_html_表单和框架
- 关于链表中头指针和头结点的理解
- c++ 封装 继承 多态
- HDU 3656 Fire station
- hdu2602 Bone Collector
- 逗号运算符
- hdoj2120 Ice_cream's word I(并查集,判断环的个数)
- 苹果API常用英语名词 (持续更新)
- Flume NG 简介及配置实战
- 多媒体容器与压缩标准的概念区别
- shell学习小结
- emacs org-reveal 创建网页版presentation