DLX重复覆盖 hdu5046 Airport_逍遥丶綦的博客-程序员秘密

技术标签: ACM_DLX  

传送门:点击打开链接

题意:有N个城市,现在要修K个机场,使N个城市到最近机场的最大距离最小,问K个机场应该修在哪里,机场必须修在城市中。

思路:二分N个城市到最近机场的最大距离,于是可以转换成,知道每个点,知道它的半径,能覆盖到这些点,问是否能选K个点,使得所在范围覆盖所有的点。那么这部分可以用DLX重复覆盖来做

wa点:二分的时候,l,m,r都要使用LL才行,因为可能会爆int

#include<map>
#include<set>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<string>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#define fuck printf("fuck")
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w+",stdout)
using namespace std;
typedef long long LL;

const int MX = 60 + 5;
const int MN = 3600 + 5;
const int INF = 0x3f3f3f3f;

struct DLX {
    int m, n, ans;
    int H[MX], S[MX], vis[MX];
    int Row[MN], Col[MN], rear;
    int L[MN], R[MN], U[MN], D[MN];

    void Init(int _m, int _n) {
        m = _m; n = _n;
        rear = n; ans = INF;
        for(int i = 0; i <= n; i++) {
            S[i] = 0;
            L[i] = i - 1;
            R[i] = i + 1;
            U[i] = D[i] = i;
        }
        L[0] = n; R[n] = 0;
        for(int i = 1; i <= m; i++) {
            H[i] = -1;
        }
    }

    void Link(int r, int c) {
        int rt = ++rear;
        Row[rt] = r; Col[rt] = c; S[c]++;

        D[rt] = D[c]; U[D[c]] = rt;
        U[rt] = c; D[c] = rt;
        if(H[r] == -1) {
            H[r] = L[rt] = R[rt] = rt;
        } else {
            int id = H[r];
            R[rt] = R[id]; L[R[id]] = rt;
            L[rt] = id; R[id] = rt;
        }
    }

    void Remove(int c) {
        for(int i = D[c]; i != c; i = D[i]) {
            R[L[i]] = R[i]; L[R[i]] = L[i];
        }
    }

    void Resume(int c) {
        for(int i = U[c]; i != c; i = U[i]) {
            R[L[i]] = L[R[i]] = i;
        }
    }

    int h() {
        int ret = 0;
        memset(vis, 0, sizeof(vis));
        for(int c = R[0]; c != 0; c = R[c]) {
            if(!vis[c]) {
                ret++;
                vis[c] = 1;
                for(int i = D[c]; i != c; i = D[i]) {
                    for(int j = R[i]; j != i; j = R[j]) {
                        vis[Col[j]] = 1;
                    }
                }
            }
        }
        return ret;
    }

    bool Dance(int cnt, int K) {
        if(cnt + h() > K) return false;
        if(R[0] == 0) return true;

        int c = R[0];
        for(int i = R[0]; i != 0; i = R[i]) {
            if(S[i] < S[c]) 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(Dance(cnt + 1, K)) return true;
            for(int j = L[i]; j != i; j = L[j]) Resume(j);
            Resume(i);
        }
        return false;
    }
} G;

LL X[MX], Y[MX], W[MX][MX];

LL dist(int i, int j) {
    return abs(X[i] - X[j]) + abs(Y[i] - Y[j]);
}

int main() {
    int T, n, K, ansk = 0; //FIN;
    scanf("%d", &T);
    while(T--) {
        scanf("%d%d", &n, &K);
        for(int i = 1; i <= n; i++) {
            scanf("%I64d%I64d", &X[i], &Y[i]);
        }
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= n; j++) {
                W[i][j] = dist(i, j);
            }
        }

        LL L = 0, R = 4e9, m, ans;
        while(L <= R) {
            m = (L + R) >> 1;

            G.Init(n, n);
            for(int i = 1; i <= n; i++) {
                for(int j = 1; j <= n; j++) {
                    if(W[i][j] <= m) G.Link(i, j);
                }
            }

            if(G.Dance(0, K)) {
                ans = m;
                R = m - 1;
            } else L = m + 1;
        }
        printf("Case #%d: %I64d\n", ++ansk, ans);
    }
    return 0;
}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qwb492859377/article/details/48930017

智能推荐

不确定性原理的前世今生(转载)_weixin_30776545的博客-程序员秘密

不确定性原理的前世今生【转】2012.04.14评论:0脚印:171不确定性原理的前世今生 · 数学篇(一)在现代数学中有一个很容易被外行误解的词汇:信号 (signal)。当数学家们说起「一个信号」的时候,他们脑海中想到的并不是交通指示灯所发出的闪烁光芒或者手机屏幕顶部的天线图案,而是一段可以具体 数字化的信息,可以是声音,可以是图像,也可是遥感测量数据。简单地说,它是一个函...

离散数学学习笔记——第四讲——谓词逻辑(第一部分)(3.3 谓词符号化)_谓词逻辑符号化_预见未来to50的博客-程序员秘密

1. 谓词逻辑符号化示例12. 谓词逻辑符号化示例23.谓词逻辑符号化示例34.谓词逻辑符号化示例4

两数相加问题 A + B Problem_LYZ0907的博客-程序员秘密

A + B Problem题目——来自hdoj Problem Description Calculate A + B. Input Each line will contain two integers A and B. Process to end of file. Output For each case, output A + B in one line

python闭包和函数调用区别_python – 函数闭包与可调用类_顽皮的张先森的博客-程序员秘密

在许多情况下,有两种实现选择:闭包和可调用类.例如,class F:def __init__(self, op):self.op = opdef __call__(self, arg1, arg2):if (self.op == 'mult'):return arg1 * arg2if (self.op == 'add'):return arg1 + arg2raise InvalidOp(op)...

swift_001(Swift的注释)_swift怎么注释掉一片代码_沐雨07的博客-程序员秘密

1、oc中使用的注释// 单行注释/*多行注释*/       #pragma marks        Comments containing:        MARK:        TODO:        FIXME:        !!!:        ???:除了使用 #pragma mark -添加分割线之外,其余的你有用过吗?

随便推点

blankelement函数C语言,C语言的10大基础算法_怪怪的我的博客-程序员秘密

C语言的10大基础算法算法是一个程序和软件的灵魂,作为一名优秀的程序员,只有对一些基础的算法有着全面的掌握,才会在设计程序和编写代码的过程中显得得心应手。本文包括了经典的Fibonacci数列、简易计算器、回文检查、质数检查等算法。也许它们能在你的毕业设计或者面试中派上用场。1、计算Fibonacci数列Fibonacci数列又称斐波那契数列,又称黄金分割数列,指的是这样一个数列:1、1、2、3、...

Command line is too long. Shorten command line for Application or aalso for Spring Boot default..._大强012的博客-程序员秘密

运行微服务报错:Error running ‘JeecgSystemCloudApplication’: Command line is too long. Shorten command line for Application or aalso for Spring Boot default configuration解决办法:修改Edit&gt;Configuration&gt;Environment&gt;Shorten command line&gt;JAR mainfest -java -

模板方法模式-覆盖策略逻辑_culi4814的博客-程序员秘密

The first time I looked at the Strategy pattern it was love at first sight. The pattern’s logic seemed to be a mythical panacea come true, where the use of Composition over Inheritance not only was ex...

maven安装配置JAVA_HOME环境变量_xueyepiaoling的博客-程序员秘密

今天碰到一个很让人火大的问题,被maven气死了!!引用:http://lansky07.javaeye.com/blog/294158今天在安装maven时安照说明配置环境变量,通过命令检查:mvn -v竟然出现以下错误,很郁闷的是我明明配置了JAVA_HOME,并且别的依赖java的东西都能用,通过java -version也可以得到配置的java home信息,却出现以下的:ERROR: JAVA_HOME is set to an invalid directory.JAVA_HOME = D:/j

计算机桌面怎么突然变大了,电脑屏幕突然变大了怎么办_秋葵葵的博客-程序员秘密

在平时的日常生活里,有时候我们使用电脑会遇到电脑屏幕突然变大了的问题,但有些新手不知道怎么做,该如何解决电脑屏幕突然变大了这个难题呢?下面是学习啦小编收集的关于电脑屏幕突然变大了的解决步骤,希望对你有所帮助。电脑屏幕突然变大了的解决步骤因为每台显示器分辨率都不一样,个人的视觉感官有所不同。适合自己就是最好的。显示器一般常见的屏幕分辨率比例、估计现在使用 4:3、 5:4的应该会少点。多见的是16:...

【锐格】数据结构-栈和队列_Do1phln的博客-程序员秘密

欢迎加入NEFU计算机编程交流群:523539085顺序栈4909#include&lt;iostream&gt;using namespace std;struct Node { int data; Node *next;};class SeqStack {private: int *array; int maxSize; int top; void stackFull();public: SeqStack(int sz=0); void Push(const

推荐文章

热门文章

相关标签