poj 2296 (2—SAT+二分)
来源:互联网 发布:php curl multi exec 编辑:程序博客网 时间:2024/05/22 16:28
继续2—SAT+二分,,n个正方形,每个点在正方形上边或下边的终点,每个点就有两种选择,2—SAT建图,,
此题有两种建图的方式:
一:分四种情况;i向上,j向上,判断两正方形是否相交,如果相交建边i—>j',j—>i';
i向上,j向下,判断两正方形是否相交,如果相交建边i—>j,j’—>i';
i向下,j向上,判断两正方形是否相交,如果相交建边i'—>j',j—>i;
i向下,j向下,判断两正方形是否相交,如果相交建边i'—>j,j'—>i;
二:直接判断两个正方形怎么放不相交,但这样的话容易漏掉应该加的边,这题的i必须向上,j必须向下的情况,
就要加上边(i+n,i),(j,j+n),表示i必须向上,j必须向下,如果不加就wrong。这种建边方式不太习惯,
#include<stdio.h>#include<string.h>#include<stack>#define N 300#define max(a,b) (a>b?a:b)#define min(a,b) (a<b?a:b)using namespace std;struct edge{int ed,next;}E[N*N];struct op{int x,y;}p[N];int low[N],dfs[N],belong[N],ins[N],idx,ans,num,first[N],n;void addedge(int x,int y){E[num].ed=y;E[num].next=first[x];first[x]=num++;}int cmp(const void *a,const void *b){struct op *c,*d;c=(struct op *)a;d=(struct op *)b;return d->y-c->y;}void insit(){memset(low,0,sizeof(low));memset(dfs,-1,sizeof(dfs));memset(belong,0,sizeof(belong));memset(ins,0,sizeof(ins));memset(first,-1,sizeof(first));idx=ans=num=0;}stack<int>Q;void Tarjan(int x){int v,p;low[x]=dfs[x]=idx++;Q.push(x);ins[x]=1;for(p=first[x];p!=-1;p=E[p].next){v=E[p].ed;if(dfs[v]==-1){Tarjan(v);low[x]=low[x]>low[v]?low[v]:low[x];}else if(ins[v]==1)low[x]=low[x]>dfs[v]?dfs[v]:low[x];}if(dfs[x]==low[x]){do{ v=Q.top(); Q.pop(); ins[v]=0; belong[v]=ans;}while(v!=x);ans++;}}bool cross(int mid,int i,int j,int s1,int s2){ double x1=p[i].x-mid/2.0,x2=p[i].x+mid/2.0; double y1=p[i].y,y2=p[i].y+s1*mid; double x3=p[j].x-mid/2.0,x4=p[j].x+mid/2.0; double y3=p[j].y,y4=p[j].y+s2*mid; if(max(x1,x2)<=min(x3,x4))return false; if(min(x1,x2)>=max(x3,x4))return false; if(max(y1,y2)<=min(y3,y4))return false; if(min(y1,y2)>=max(y3,y4))return false; return true;}int judge(int d){int i,j;insit();for(i=0;i<n;i++)for(j=i+1;j<n;j++){ //*********************************************************************************/*if(abs(p[i].x-p[j].x)>=d)continue;//横坐标的距离大于d,怎么放都不会重合if(p[i].y-p[j].y>=2*d)continue;//纵坐标大于2d,if(p[i].y-p[j].y<d)//距离小于d,只能一上一下{ if(p[i].y==p[j].y) { addedge(i,j+n);//i上,j下 addedge(j,i+n);//j上,i下 addedge(i+n,j); addedge(j+n,i); } else { addedge(i,j+n);//i向上,j向下(i与j矛盾) addedge(i+n,i);//i一定向上 addedge(j,j+n);//j一定向下 addedge(j+n,i);//(j'与i'矛盾) }}else if(p[i].y-p[j].y<2*d){addedge(i+n,j+n);//都向下addedge(j,i);//都向上}*/ //*********************************************************************************if(cross(d,i,j,1,1))//1代表向上,-1代表向下{ addedge(i,j+n); addedge(j,i+n);}if(cross(d,i,j,1,-1)){addedge(i,j);addedge(j+n,i+n);}if(cross(d,i,j,-1,1)){addedge(i+n,j+n);addedge(j,i);}if(cross(d,i,j,-1,-1)){addedge(i+n,j);addedge(j+n,i);}}for(i=0;i<n*2;i++)if(dfs[i]==-1)Tarjan(i);for(i=0;i<n;i++)if(belong[i]==belong[i+n])return 0;return 1;}int main(){int i,t,min,max,mid,sum;scanf("%d",&t);while(t--){scanf("%d",&n);for(i=0;i<n;i++)scanf("%d%d",&p[i].x,&p[i].y);qsort(p,n,sizeof(p[0]),cmp);min=0;max=20000;sum=0;while(min<=max){mid=(min+max)/2;if(judge(mid)){sum=mid;min=mid+1;}else max=mid-1;}printf("%d\n",sum);}return 0;}
- poj 2296 (2—SAT+二分)
- poj 2296 二分+2-sat
- Map Labeler (poj 2296 二分+2-SAT)
- POJ 2296 Map Labeler 2-SAT 二分
- POJ 2296 Map Labeler(二分+2-SAT)
- |poj 2296|2-SAT|二分|Map Labeler
- poj 2723【2-SAT+二分】
- 【2-SAT+二分】POJ 2749
- poj 2296 Map Labeler(二分+2-sat判定)
- POJ 2296 Map Labeler ( 2-SAT判定 + 二分查找 )
- POJ 2296 Map Labeler(2-SAT+二分)
- POJ 2296 Map Labeler (二分+2-sat,4级)
- POJ 2296 Map Labeler 2-SAT+二分答案
- poj 2296 Map Labeler(2-SAT+二分,构图)
- poj 2296 Map Labeler (2-sat +二分)
- hdu 1815,poj 2749 (2—SAT+二分)
- POJ--2749[Building roads] 2-SAT第五题,2—SAT+二分判定
- POJ 2723 二分+ 2-sat 判定
- 初入USACO小练
- free函数在操作系统内存中的实现
- plsql 打开游标碰到了一个奇怪的问题。
- 优秀侧滑菜单设计案例
- 使用构造函数初始化列表
- poj 2296 (2—SAT+二分)
- 理解BW数据模型 - 主数据模型
- 五种内存处理基本工具
- SQL注入
- windows内存堆的数据结构
- 高并发量网站解决方案
- Nginx介绍
- ExtJS(一)JavaScript基础--网页打字游戏
- Android开发_程序中启动另一个程序