zoukankan      html  css  js  c++  java
  • hdu 2295 Radar 重复覆盖+二分

    题目链接

    给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
    ", l);
        }
    }dlx;
    int main()
    {
        int t;
        cin>>t;
        while(t--) {
            scanf("%d%d%d", &dlx.n, &dlx.m, &dlx.k);
            dlx.solve();
        }
        return 0;
    }
  • 相关阅读:
    混沌的艺术--- YChaos通过数学公式生成混沌图像
    相声段子:How Are You
    太阳崇拜---64幅由算法生成的八芒星图像
    自然的密码---36幅由算法生成的六芒星图像
    雪花六出---几幅算法生成的雪花图像,并祝大家平安夜和圣诞节快乐
    18个分形图形的GIF动画演示
    python的with用法(参考)
    彻底解决django 2.2以上版本与mysql兼容性问题(不用改源码)
    python操作MySQL数据库的三个模块
    MySql 外键约束 之CASCADE、SET NULL、RESTRICT、NO ACTION分析和作用
  • 原文地址:https://www.cnblogs.com/yohaha/p/5049606.html
Copyright © 2011-2022 走看看