首页 > 其他 > 详细

hdu 2295 Radar 重复覆盖+二分

时间:2015-12-15 22:36:30      阅读:387      评论:0      收藏:0      [点我收藏+]

题目链接

给m个雷达, n个城市, 以及每个城市的坐标, m个雷达里只能使用k个, 在k个雷达包围所有城市的前提下, 求最小半径。

先求出每个雷达到所有城市的距离, 然后二分半径, 如果距离小于二分的值, 就加边(大概不叫加边, 我也不知道叫什么......

#include<bits/stdc++.h>
using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<1|1
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, a, n) for(int i = a; i<n; i++)
#define ull unsigned long long
typedef pair<int, int> pll;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int mod = 1e9+7;
const int inf = 1061109567;
const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
const int maxn = 305;
const int maxNode = 5000;
struct node
{
    int x, y;
}a[51], b[51];
struct DLX {
    int L[maxNode], R[maxNode], U[maxNode], D[maxNode], row[maxNode], col[maxNode];
    int S[maxn], H[maxn], deep, ans[maxn], sz, n, m, k;
    double g[52][52];
    void remove(int c) {
        for(int i = D[c]; i!=c; i = D[i]) {
            L[R[i]] = L[i];
            R[L[i]] = R[i];
        }
    }
    void resume(int c) {
        for(int i = U[c]; i!=c; i = U[i]) {
            L[R[i]] = i;
            R[L[i]] = i;
        }
    }
    int h() {
        int cnt = 0;
        int vis[105];
        mem(vis);
        for(int i = R[0]; i!=0; i = R[i]) {
            if(!vis[i]) {
                cnt++;
                vis[i] = 1;
                for(int j = D[i]; j!=i; j = D[j]) {
                    for(int k = R[j]; k!=j; k = R[k]) {
                        vis[col[k]] = 1;
                    }
                }
            }
        }
        return cnt;
    }
    int dfs(int d) {
        if(d+h()>k)
            return 0;
        if(R[0] == 0) {
            return 1;
        }
        int c = R[0];
        for(int i = R[0]; i!=0; i = R[i])
            if(S[c]>S[i])
                c = i;
        for(int i = D[c]; i!=c; i = D[i]) {
            remove(i);
            for(int j = R[i]; j!=i; j = R[j])
                remove(j);
            if(dfs(d+1))
                return 1;
            for(int j = L[i]; j!=i; j = L[j])
                resume(j);
            resume(i);
        }
        return 0;
    }
    void add(int r, int c) {
        sz++;
        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]) {
            R[sz] = H[r];
            L[sz] = L[H[r]];
            L[R[sz]] = sz;
            R[L[sz]] = sz;
        } else {
            H[r] = L[sz] = R[sz] = sz;
        }
    }
    void init(){
        mem1(H);
        for(int i = 0; i<=n; i++) {
            R[i] = i+1;
            L[i] = i-1;
            U[i] = i;
            D[i] = i;
        }
        mem(S);
        R[n] = 0;
        L[0] = n;
        sz = n;
    }
    double dis(int i, int j) {
        return sqrt(1.0*(b[i].x-a[j].x)*(b[i].x-a[j].x)+(b[i].y-a[j].y)*(b[i].y-a[j].y));
    }
    int check(double mid) {
        init();
        for(int i = 1; i<=m; i++) {
            for(int j = 1; j<=n; j++) {
                if(mid-g[i][j]>=eps) {
                    add(i, j);
                }
            }
        }
        if(dfs(0))
            return 1;
        return 0;
    }
    void solve() {
        mem(g);
        for(int i = 1; i<=n; i++)
            scanf("%d%d", &a[i].x, &a[i].y);
        for(int i = 1; i<=m; i++)
            scanf("%d%d", &b[i].x, &b[i].y);
        for(int i = 1; i<=m; i++) {
            for(int j = 1; j<=n; j++) {
                g[i][j] = dis(i, j);
            }
        }
        double l = 0, r = 3000;
        while(r-l>eps) {
            double mid = (l+r)/2;
            if(check(mid))
                r = mid;
            else
                l = mid;
        }
        printf("%.6f\n", l);
    }
}dlx;
int main()
{
    int t;
    cin>>t;
    while(t--) {
        scanf("%d%d%d", &dlx.n, &dlx.m, &dlx.k);
        dlx.solve();
    }
    return 0;
}

 

hdu 2295 Radar 重复覆盖+二分

原文:http://www.cnblogs.com/yohaha/p/5049606.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!