poj 2296 2-SAT(无矩形相交的最大边长)
来源:互联网 发布:统计贸易数据自查报告 编辑:程序博客网 时间:2024/04/30 18:07
题意:欲在平面直角坐标系上贴n个边长相同的正方形标签,要求标签不能重合。输入为n个点(给出坐标)。要求每个点是在标签的下边中点或者上边中点出,求符合题意的标签的最大边长。
思路:2-SAT+二分答案。
首先二分枚举答案。对每一对点,标签的位置由四种情况,枚举这四种情况,判断标签是否相交,如此建图。转化为tarjan算法解决的2-SAT问题。
#include <stdio.h>#include <string.h>#define max(a,b) ((a)>(b)?(a):(b))#define min(a,b) ((a)<(b)?(a):(b))#define N 1005struct edge{int x,y,next;}e[N*N];struct point{int x,y;}p[N];int n,T,top,lo,high,mid,res,index,num,tops;int first[N],dfn[N],low[N],strong[N],stack[N];void init(){top = index = num = 0;tops = -1;memset(first,-1,sizeof(first));memset(dfn,-1,sizeof(dfn));memset(strong,0,sizeof(strong));}void add(int x,int y){e[top].y = y;e[top].next = first[x];first[x] = top++;}int test_cross(int i,int j,int len,int or1,int or2){//判断两个正方形是否相交double x1_left = p[i].x - len/2.;double x1_right = p[i].x + len/2.;double x2_left = p[j].x - len/2.;double x2_right = p[j].x + len/2.;int y1_1 = p[i].y;int y1_2 = p[i].y + or1*len;int y2_1 = p[j].y;int y2_2 = p[j].y + or2*len;if((x1_right>x2_left) && (x2_right>x1_left) &&max(y1_1,y1_2) > min(y2_1,y2_2) &&max(y2_1,y2_2) > min(y1_1,y1_2) )return 1;return 0;}void tarjan(int x){int i;dfn[x] = low[x] = ++index;stack[++tops] = x;for(i=first[x];i!=-1;i=e[i].next){if(dfn[e[i].y] == -1){tarjan(e[i].y);low[x] = min(low[x],low[e[i].y]);}else if(!strong[e[i].y])low[x] = min(low[x],dfn[e[i].y]);}if(dfn[x] == low[x]){num++;do{strong[stack[tops]] = num;}while(stack[tops--]!=x);}}int main(){freopen("a.txt","r",stdin);scanf("%d",&T);while(T--){int i,j;lo = 0;high = 10000;//二分答案scanf("%d",&n);for(i = 1;i<=n;i++)scanf("%d %d",&p[i].x,&p[i].y);while(lo <= high){init();//注意初始化的位置mid = (lo+high)>>1;for(i = 1;i<n;i++)//建图for(j = i+1;j<=n;j++){if(test_cross(i,j,mid,-1,-1))add(i,j+n),add(j,i+n);if(test_cross(i,j,mid,-1,1))add(i,j),add(j+n,i+n);if(test_cross(i,j,mid,1,-1))add(i+n,j+n),add(j,i);if(test_cross(i,j,mid,1,1))add(i+n,j),add(j+n,i);}for(i = 1;i<=2*n;i++)//tarjan求强连通分量if(dfn[i] == -1)tarjan(i);for(i = 1;i<=n;i++)if(strong[i] == strong[i+n])//如果有一个点的两种情况在同一个连通分量中(也就是必须同时满足)break;if(i > n){//答案合理res = mid;lo = mid+1;}elsehigh = mid-1;}printf("%d\n",res);}return 0;}
0 0
- poj 2296 2-SAT(无矩形相交的最大边长)
- POJ 2296 Map Labeler(二分边长+2-sat判解)(经典题)
- POJ 2296Map Labeler 2-sat + 矩阵相交
- 求最大正方形的边长
- poj 3207 2-SAT(圆周点连边不相交)
- 【POJ】2482 矩形相交面积的变形体(重要)
- 矩形相交的面积
- POJ 2559 最大矩形。。
- 上传图片最大允许的边长Ueditor
- 求三个矩形的相交矩形。
- poj 1410 矩形与线段相交判断
- poj 1410 线段与矩形相交
- POJ 1410 || Intersection(线段矩形相交
- 计算两个矩形是否相交以及相交的矩形
- 矩形相交区域的计算
- 矩形相交区域的计算
- poj 2296 二分+2-sat
- 设计矩形类矩形,允许用户输入其边长,计算出该矩形的面积和周长。
- 奇怪的分式
- 东软学习,sql工具类
- 合同如火如荼有态度与合同任何人
- uva 10288 - Coupons(概率)
- 2014腾讯实习校招
- poj 2296 2-SAT(无矩形相交的最大边长)
- Porting WiFi drivers to Android
- 1050 moving table
- 有罪推定
- MySQL存储二进制数据
- iOS应用程序生命周期各个函数方法详解
- 和他人还让他好如同废物染发如果风王夫人个人各
- 【NOIP模拟】20140809 题解 & 总结
- 死亡游戏(链表)