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
Sample Output
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< ...
随机推荐
- Android 歌词显示
一.概述 项目中设计到歌词显示的问题,这一块之前没有涉及过,只是套用过一个开源的项目,效果还行,于是想到拿来稍作修改,以适应项目需求. 二.歌词控件 先来看下这个自定义控件写的歌词控件吧: publi ...
- LoadRunner监控Tomcat的几种方法
通过JConsole监控Tomcat 1.打开tomcat5的bin目录中的catalina.bat文件,在头部注释部分的后面加上: set JAVA_OPTS=%JAVA_OPTS% -Dcom.s ...
- 数学之路-分布式计算-linux/unix技术基础(4)
pwd显示当前文件夹,ls查看文件夹下的文件,cd 进入文件夹 -bash-4.2$ pwd /home/myhaspl-bash-4.2$ lsabc hadoop-2.4.1 ...
- Java的内存机制(转)
0.参考资料: http://www.j2megame.org/index.php/content/view/2246/125.html 1.Java的内存机制 Java 把内存划分成两种:一种是栈内 ...
- 【微信小程序】获取轮播图当前图片下标、滑动展示对应的位数、点击位数展示对应图片
业务需求: 3个图片轮番播放,可以左右滑动,点击指示点可以切换图片 index.wxml: 这里使用小程序提供的<swiper>组件autoplay:自动播放interval:自动切换时 ...
- CodeIgniter 2.X 于 PHP5.6 兼容错误
本篇文章由:http://xinpure.com/codeigniter-2-x-to-php5-6-compatible-error/ CI 3.0 已兼容此问题 在代码迁移的过程中,遇到了一个 P ...
- 电子商务(电销)平台中订单模块(Order)数据库设计明细(转载)
电子商务(电销)平台中订单模块(Order)数据库设计明细 以下是自己在电子商务系统设计中的订单模块的数据库设计经验总结,而今发表出来一起分享,如有不当,欢迎跟帖讨论~ 订单表 (order)|-- ...
- [转载]Scikit-learn介绍几种常用的特征选择方法
#### [转载]原文地址:http://dataunion.org/14072.html 特征选择(排序)对于数据科学家.机器学习从业者来说非常重要.好的特征选择能够提升模型的性能,更能帮助我们理解 ...
- ASP.NET 之XML:要插入的节点出自不同的文档上下文
异常详细信息: System.ArgumentException: 要插入的节点出自不同的文档上下文. 产生状况:现在有两个xml文件,我想把这两个xml合并,在给xml节点插入一个子节点时出 ...
- unity, Destroy注意事项
Destroy不是立即发生作用,而是推迟到帧末,所以下面代码是错误的: void OnTriggerEnter(Collider other){ if (other.gameObject.tag ...