Map Labeler (poj 2296 二分+2-SAT)
Language:
Default
Map Labeler
Description
Map generation is a difficult task in cartography. A vital part of such task is automatic labeling of the cities in a map; where for each city there is text label to be attached to its location, so that no two labels overlap. In this problem, we are concerned
with a simple case of automatic map labeling. Assume that each city is a point on the plane, and its label is a text bounded in a square with edges parallel to x and y axis. The label of each city should be located such that the city point appears exactly in the middle of the top or bottom edges of the label. In a good labeling, the square labels are all of the same size, and no two labels overlap, although they may share one edge. Figure 1 depicts an example of a good labeling (the texts of the labels are not shown.) Given the coordinates of all city points on the map as integer values, you are to find the maximum label size (an integer value) such that a good labeling exists for the map. ![]() Input
The first line contains a single integer t (1 <= t <= 10), the number of test cases. Each test case starts with a line containing an integer m (3 ≤ m ≤ 100), the number of cities followed by m lines of data each containing a pair of integers; the first integer
(X) is the x and the second one (Y) is the y coordinates of one city on the map (-10000 ≤X, Y≤ 10000). Note that no two cities have the same (x, y) coordinates. Output
The output will be one line per each test case containing the maximum possible label size (an integer value) for a good labeling.
Sample Input 1 Sample Output 2 Source |
题意:平面上有n个点。每一个点画一个正方形而且该点要落在正方形上边或者下边的中间。问满足条件的最大正方形的边长是多少。
思路:二分边长mid,建图用2-SAT作为推断条件。
i表示画在上面。~i表示画在以下
if|xi-xj|>=mid continue;
else if |yi-yj|>=2*mid continue;
else if |yi-yj|==0 then i->~j,~i->j,j->~i,~j->i;
else if |yi-yj|>0 then ~i->i,j->~j;
else |yi-yj|>=mid then j->i,~i->~j;
代码:
#include <iostream>
#include <functional>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#pragma comment (linker,"/STACK:102400000,102400000")
#define pi acos(-1.0)
#define eps 1e-6
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define FRE(i,a,b) for(i = a; i <= b; i++)
#define FREE(i,a,b) for(i = a; i >= b; i--)
#define FRL(i,a,b) for(i = a; i < b; i++)
#define FRLL(i,a,b) for(i = a; i > b; i--)
#define mem(t, v) memset ((t) , v, sizeof(t))
#define sf(n) scanf("%d", &n)
#define sff(a,b) scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define pf printf
#define DBG pf("Hi\n")
typedef long long ll;
using namespace std; #define INF 0x3f3f3f3f
#define mod 1000000009
const int maxn = 1005;
const int MAXN = 2005;
const int MAXM = 20010;
const int N = 1005; struct Node
{
int x,y;
}node[MAXN]; struct Edge
{
int to,next;
}edge[MAXM]; int tot,head[MAXN];
int Low[MAXN],DFN[MAXN],Stack[MAXN],Belong[MAXN];
bool Instack[MAXN];
int top,scc,Index; void init()
{
tot=0;
memset(head,-1,sizeof(head));
} void addedge(int u,int v)
{
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot++;
} void Tarjan(int u)
{
int v;
Low[u]=DFN[u]=Index++;
Instack[u]=true;
Stack[top++]=u;
for (int i=head[u];~i;i=edge[i].next)
{
int v=edge[i].to;
if (!DFN[v])
{
Tarjan(v);
if (Low[u]>Low[v]) Low[u]=Low[v];
}
else if (Instack[v]&&Low[u]>DFN[v])
Low[u]=DFN[v];
}
if (Low[u]==DFN[u])
{
scc++;
do{
v=Stack[--top];
Instack[v]=false;
Belong[v]=scc;
}while (v!=u);
}
return ;
} bool solvable(int n)
{
memset(DFN,0,sizeof(DFN));
memset(Instack,false,sizeof(Instack));
top=scc=Index=0;
for (int i=0;i<n;i++)
{
if (!DFN[i])
Tarjan(i);
}
for (int i=0;i<n;i+=2)
{
if (Belong[i]==Belong[i^1])
return false;
}
return true;
} bool isok(int mid,int n) //依据mid建图
{
init();
for (int i=0;i<n;i++)
{
for (int j=i+1;j<n;j++)
{
if (abs(node[i].x-node[j].x)>=mid) continue;
if (abs(node[i].y-node[j].y)>=2*mid) continue;
if (node[i].y==node[j].y)
{
addedge(2*i,2*j+1);
addedge(2*j+1,2*i);
addedge(2*j,2*i+1);
addedge(2*i+1,2*j);
}
else if (node[i].y-node[j].y>0&&node[i].y-node[j].y<mid)
{
addedge(2*i+1,2*i);
addedge(2*j,2*j+1);
}
else if (node[j].y-node[i].y>0&&node[j].y-node[i].y<mid)
{
addedge(2*j+1,2*j);
addedge(2*i,2*i+1);
}
else if (node[i].y-node[j].y>=mid)
{
addedge(2*i+1,2*j+1);
addedge(2*j,2*i);
}
else if (node[j].y-node[i].y>=mid)
{
addedge(2*j+1,2*i+1);
addedge(2*i,2*j);
}
}
}
if (solvable(2*n)) return true;
return false;
} void solve(int n) //二分
{
int l=0,r=10000,ans;
while (l<=r)
{
// DBG;
int mid=(l+r)>>1;
if (isok(mid,n))
{
// DBG;
ans=mid;
l=mid+1;
}
else r=mid-1;
}
printf("%d\n",ans);
} int main()
{
#ifndef ONLINE_JUDGE
freopen("C:/Users/lyf/Desktop/IN.txt","r",stdin);
#endif
int i,j,t,m;
scanf("%d",&t);
while (t--)
{
scanf("%d",&m);
for (i=0;i<m;i++)
scanf("%d%d",&node[i].x,&node[i].y);
solve(m);
}
return 0;
}
Map Labeler (poj 2296 二分+2-SAT)的更多相关文章
- Map Labeler POJ - 2296(2 - sat 具体关系建边)
题意: 给出n个点 让求这n个点所能建成的正方形的最大边长,要求不覆盖,且这n个点在正方形上或下边的中点位置 解析: 当然是二分,但建图就有点还行..比较难想..行吧...我太垃圾... 2 - s ...
- POJ 2296 Map Labeler / ZOJ 2493 Map Labeler / HIT 2369 Map Labeler / UVAlive 2973 Map Labeler(2-sat 二分)
POJ 2296 Map Labeler / ZOJ 2493 Map Labeler / HIT 2369 Map Labeler / UVAlive 2973 Map Labeler(2-sat ...
- POJ 2296 二分+2-sat
题目大意: 给定n个点,给每个点都安排一个相同的正方形,使这个点落在正方形的下底边的中间或者上底边的中间,并让这n个正方形不出现相互覆盖,可以共享同一条边,求 这个正方形最大的边长 这里明显看出n个点 ...
- POJ 2296 Map Labeler(2-sat)
POJ 2296 Map Labeler 题目链接 题意: 坐标轴上有N个点.要在每一个点上贴一个正方形,这个正方形的横竖边分别和x,y轴平行,而且要使得点要么在正方形的上面那条边的中点,或者在以下那 ...
- POJ 2296 Map Labeler (2-Sat)
Map Labeler Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 1267 Accepted: 409 Descri ...
- POJ - 2018 二分+单调子段和
依然是学习分析方法的一道题 求一个长度为n的序列中的一个平均值最大且长度不小于L的子段,输出最大平均值 最值问题可二分,从而转变为判定性问题:是否存在长度大于等于L且平均值大于等于mid的字段和 每个 ...
- poj 2296
Map Labeler Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 2047 Accepted: 682 Descri ...
- 【POJ】2296 Map Labeler
http://poj.org/problem?id=2296 题意:题意:给你n个点,每个点上都放一个正方形,点只能在正方形的上边或下边的中点上,所有正方形大小一样,不能有面积重叠,求最大的正方形.( ...
- POJ 2296 Map Labeler
二分答案 + 2-SAT验证,判断正方形是否相交写起来有点烦,思路还是挺简单的. #include<cstdio> #include<cstring> #include< ...
随机推荐
- 算法笔记_070:BellmanFord算法简单介绍(Java)
目录 1 问题描述 2 解决方案 2.1 具体编码 1 问题描述 何为BellmanFord算法? BellmanFord算法功能:给定一个加权连通图,选取一个顶点,称为起点,求取起点到其它所有顶 ...
- Vue props 单向数据流
1.props通信 注意:DOM模板的驼峰命名props要转为短横分割命名. <!DOCTYPE html> <html lang="zh"> <he ...
- [IOS A] - 一些开源类库
因 为iOS SDK相对比较底层,所以开发者就得受累多做一些体力活.不过幸运的是,有很多第三方的类库可以用来简化很多不必要的工作.笔者整理了一下在本人学习过程 中用到的一些比较有用Objective- ...
- FIFO、LRU、LFU的含义和原理(转)
题目:请简要介绍FIFO.LRU.LFU的含义和原理 含义: FIFO:First In First Out,先进先出LRU:Least Recently Used,最近最少使用 LFU:Leas ...
- log4j 配置(转)
log4j是干什么的 log4j是Apache的一个开源项目,主要功能是打印日志信息,以各种形式在各种地方花式打印日志. 使用log4j的准备工作 使用log4j就必须要引入其jar包.附上官网地址h ...
- Android studio 使用心得(三)—从Eclipse迁移到Android studio
断断续续的也算是把eclipse上的代码成功迁移到android studio上来了,现在,我同事继续用eclipse,我用android studio,svn上还是之前eclipse的项目,迁移成功 ...
- Solr3.6.2和Solr4.9.0经常使用配置
tomcat 以tomcat 7为例,位置/work/apache-tomcat-7.0.55 Solr 3.6.2 基本配置 Solr 3.6.2.须要JDK 6/JDK7支持. 下载Solr 3. ...
- Mac 全局变量 ~/.bash_profile 文件不存在的问题
不存在就新建呗~ $ cd ~/ $ touch .bash_profile $ open -e .bash_profile 然后输入以下内容 # set color的部分是配置iterm2的字体颜色 ...
- Bash中的括号(三)
1.两个小括号用来对整数进行算术运算和逻辑运算,比如. 例如给变量赋值: $ a=+; echo $a + $ (( b = + )); echo $b 1+1 只是一个字符串,而 b 就是一个算术表 ...
- SYN攻击防护措施
SYN攻击的应对措施 针对SYN攻击的几个环节.提出对应的处理方法: 方式1:降低SYN-ACK数据包的重发次数(默认是5次): sysctl -w net.ipv4.tcp_synack_retri ...