`
king_tt
  • 浏览: 2290357 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

POJ 2296 Map Labeler(2-SAT+二分)

 
阅读更多

【题目链接】

http://poj.org/problem?id=2296


【题目大意】

坐标轴上有N个点,要在每个点上贴一个正方形,这个正方形的横竖边分别和x,y轴平行,并且要使得点要么在正方形的上面那条边的中点,或者在下面那条边的中点,并且任意两个点的正方形都不重叠(可以重边)。问正方形最大边长可以多少?


【思路】

可以很容易的看出,正方形要么在点的上方,要么在下方,所以是用2-SAT来判断的,关键是加边的判断,要涉及到两个正方形的位置的重叠关系比较麻烦。

然后二分正方形的边长即可。



【代码】

#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
using namespace std;

const int MAXN = 110;
const int VN   = MAXN*2;
const int EN   = VN*VN*2*10;
const int INF  = 0x3f3f3f3f;

int n;

int Abs(int n){
    return n<0?-n:n;
}

struct Node{
    int x, y;
}arr[MAXN];

struct Graph{
    int size, head[VN];
    struct{int v, next; }E[EN];
    void init(){size=0; memset(head, -1, sizeof(head)); };
    void addEdge(int u, int v){
        E[size].v = v;
        E[size].next = head[u];
        head[u] = size++;
    }
}g;

class Two_Sat{
public:
    bool check(const Graph& g, const int n){
        scc(g, 2*n);
        for(int i=0; i<n; ++i)
            if(belong[i] == belong[i+n])
                return false;
        return true;
    }
private:
    void tarjan(const Graph& g, const int u){
        int v;
        dfn[u] = low[u] = ++idx;
        sta[top++] = u;
        instack[u] = true;

        for(int e=g.head[u]; e!=-1; e=g.E[e].next){
            v = g.E[e].v;
            if(dfn[v] == -1){
                tarjan(g, v);
                low[u] = min(low[u], low[v]);
            }else if(instack[v]){
                low[u] = min(low[u], dfn[v]);   
            }
        }

        if(dfn[u] == low[u]){
            ++bcnt;
            do{
                v = sta[--top];
                instack[v] = false;
                belong[v] = bcnt;
            }while(u != v);
        }
    }
    
    void scc(const Graph& g, const int n){
        idx = top = bcnt = 0;
        memset(dfn, -1, sizeof(dfn));
        memset(instack, 0, sizeof(instack));
        for(int i=0; i<n; ++i){
            if(dfn[i] == -1)
                tarjan(g, i);
        }
    }

private:
    int idx, top, bcnt;
    int dfn[VN], low[VN], sta[VN], belong[VN];
    bool instack[VN];
}sat;

void buildGraph(int r){
    g.init();
    for(int i=0; i<n; ++i){
        for(int j=i+1; j<n; ++j){
            if(Abs(arr[i].x-arr[j].x) >= r) continue;
            if(Abs(arr[i].y-arr[j].y) >= 2*r) continue;
            if(Abs(arr[i].y-arr[j].y) < r){
                if(arr[i].y > arr[j].y){ // i在上面
                    g.addEdge(i, j+n);
                    g.addEdge(i+n, i);
                    g.addEdge(j, j+n);
                    g.addEdge(j+n, i);
                }else if(arr[i].y < arr[j].y){
                    g.addEdge(j, i+n);
                    g.addEdge(j+n, j);
                    g.addEdge(i, i+n);
                    g.addEdge(i+n, j);
                }else{
                    g.addEdge(i, j+n);
                    g.addEdge(i+n, j);
                    g.addEdge(j, i+n);
                    g.addEdge(j+n, i);
                }
                
            }else{
                if(arr[i].y > arr[j].y){
                    g.addEdge(i+n, j+n);
                    g.addEdge(j, i);
                }else{
                    g.addEdge(j+n, i+n);
                    g.addEdge(i, j);
                }
            }
        }
    }
}

int main(){
    
    int nCase;
    scanf("%d", &nCase);

    while(nCase--){
        
        scanf("%d", &n);

        for(int i=0; i<n; ++i)
            scanf("%d%d", &arr[i].x, &arr[i].y);

        int l=0;  
        int r=20000, m;
        int ans=0; 
        while(l < r){ // 二分边长
            m = (l+r)>>1;
            buildGraph(m);
            if(sat.check(g, n)){
                ans = m;
                l=m+1;
            } else r=m;
        }
        printf("%d\n", ans);
    }
    return 0;
}


分享到:
评论

相关推荐

    POJ3253-POJ3253-Fence Repair【STL优先队列】

    2. "POJ3253-POJ3253-Fence Repair【STL优先队列】.cpp":这是使用STL中的优先队列数据结构来解决题目的代码。 3. "POJ3253-POJ3253-Fence Repair【朴素思想TLE】.cpp":这个文件可能包含了没有利用优先队列,而是...

    POJ3009-Curling 2.0【DFS+Vector+回溯+剪枝】

    《POJ3009-Curling 2.0:深度优先搜索、向量、回溯与剪枝的综合应用》 北京大学在线编程平台上的POJ3009题目名为"Curling 2.0",它是一道涉及到算法与数据结构的复杂问题,主要考察了参赛者对深度优先搜索(DFS)、...

    POJ3733-Changing Digits【DFS+强剪枝】

    【标题】"POJ3733-Changing Digits【DFS+强剪枝】"是一个来自北京大学在线评测系统POJ的编程题目,该题目主要涉及深度优先搜索(DFS)算法和强剪枝策略。在算法竞赛和编程挑战中,这类问题通常要求参赛者通过编写...

    POJ3026-Borg Maze【BFS+Prim】

    《POJ3026-Borg Maze:BFS与Prim算法的应用解析》 在计算机科学领域,图论是解决问题的重要工具之一,而BFS(广度优先搜索)和Prim算法则是其中的两种经典算法。本篇文章将围绕北大POJ3026题目“Borg Maze”来探讨...

    POJ2186-Popular Cows【Tarjan+极大强连通分量+缩点】

    POJ2186-Popular Cows 【Tarjan+极大强连通分量+缩点】 解题报告+AC代码 http://hi.csdn.net/!s/BGDH68 附:我所有的POJ解题报告链接 . http://blog.csdn.net/lyy289065406/article/details/6642573

    POJ1002-487-3279【Hash+Qsort】

    2. "POJ1002-487-3279【Qsort】.cpp":这个可能是单独实现快速排序部分的代码,可能用于比较不同的排序方法或作为哈希+快速排序方案的一部分。 3. "POJ1002-487-3279.doc":这是一个文档文件,很可能包含了详细的...

    POJ3373-Changing Digits【DFS+强剪枝】

    标题“POJ3373-Changing Digits【DFS+强剪枝】”涉及的是一个编程竞赛中的问题,这个问题在北大POJ(北京大学在线评测系统)平台上被提出。"Changing Digits"是一个算法挑战,而解决方案是通过深度优先搜索(DFS)...

    POJ 分类题目

    二分查找适用于有序数组。 - **示例题目**: - poj3349 - poj3274 - poj2151 - poj1840 - poj2002 - poj2503 - **应用场景**:适用于快速查找、统计频率等问题。 **5. 哈夫曼树** - **定义**:一种带权路径...

    北大POJ初级-所有题目AC代码+解题报告

    【标题】"北大POJ初级-所有题目AC代码+解题报告" 涉及的知识点主要集中在编程、算法和在线判题系统方面。北京大学(Peking University, 简称PKU)的POJ(Peking University Online Judge)是一个为计算机科学爱好者...

    poj 1690 Your-Term-Project.md

    poj 1690 Your-Term-Project.md

    poj 1240 Pre-Post-erous!.md

    poj 1240 Pre-Post-erous!.md

    POJ水题集--50道--增加自信

    POJ水题集-----50道左右-----增加自信啊..

    poj-1028-Web-Navigation.zip_poj

    【标题】"poj-1028-Web-Navigation.zip_poj" 指向的是一个编程竞赛问题,POJ(Programming Online Judge)平台上的第1028题,名为“Web Navigation”。该问题通常涉及到算法设计和实现,可能是为了考察参赛者的编程...

    ACM------搜索+(从入门到精通)

    非常详细的ACM 搜索类型题 配套POJ练习,有详细思路

    pku(poj)--2494--Acid Text--java代码

    根据给定的文件信息,我们可以总结出以下关于POJ(PKU)问题2494“Acid Text”以及其Java代码实现的关键知识点: ### 1. POJ(PKU)2494:Acid Text POJ(Peking University Online Judge)是北京大学的一个在线...

    poj(PKU-2314-POJ language

    根据提供的文件信息,我们可以分析出该段代码是用于解决POJ平台上的2314题的一种解决方案,主要涉及到了变量管理、表达式处理等方面。下面将详细解释代码中的关键概念和实现逻辑。 ### 关键概念解析 #### Variable...

    poj多道----acm----解题报告

    在二维平面上,这可以通过链表或数组来实现,将每个顶点作为链表或数组的一个节点,并保证首尾相连。 3. **判断点灯位置**:检查灯的位置是否在多边形内部。这可以通过射线交叉法实现,即从灯的位置向任意方向发射...

    POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类

    - **例题**:poj1860, poj3259, poj1062, poj2253, poj1125, poj2240 - **解释**:最短路径算法包括Dijkstra算法、Bellman-Ford算法、Floyd算法以及堆优化的Dijkstra算法等。 ##### (3) 最小生成树算法 - **例题**...

    POJ1207-The 3n + 1 problem

    此外,对于大型数据,还可以考虑使用更高效的数据结构和算法优化,例如二分查找、位运算等。然而,对于POJ1207的规模,上述的简单动态规划方法已经足够高效。 总的来说,解答《POJ1207-The 3n + 1 problem》不仅...

    北大POJ初级题-数据结构:解题报告+AC代码

    北京大学在线判题系统POJ(Problem Online Judge)是许多编程爱好者和学习者锻炼算法技能的平台,特别是对于初学者,它提供了很多基础题目来帮助理解并应用数据结构。本资源包含的是北大POJ初级题目的解题报告以及...

Global site tag (gtag.js) - Google Analytics