POJ 2296 Map Labeler
二分答案 + 2-SAT验证,判断正方形是否相交写起来有点烦,思路还是挺简单的。
#include<cstdio> #include<cstring> #include<cmath> #include<stack> #include<queue> #include<algorithm> using namespace std; const int maxn=1005; struct Point { double x,y; }p[maxn]; int N; stack<int>S; vector<int>G[maxn]; vector<int>FG[maxn]; int Belong[maxn]; int flag[maxn]; int Block; int left,right,mid,ans; void init() { for(int i=0; i<maxn; i++) G[i].clear(); for(int i=0; i<maxn; i++) FG[i].clear(); memset(Belong,0,sizeof Belong); memset(flag,0,sizeof flag); while(!S.empty()) S.pop(); Block=0; } void addEdge(int x,int y) { G[x].push_back(y); FG[y].push_back(x); } void dfs1(int now) { flag[now]=1; for(int i=0; i<G[now].size(); i++) if(!flag[G[now][i]]) dfs1(G[now][i]); S.push(now); } void dfs2(int now) { Belong[now]=Block; for(int i=0; i<FG[now].size(); i++) if(!Belong[FG[now][i]]) dfs2(FG[now][i]); } bool judge() { for(int i=0; i<2*N; i++) if(!flag[i]) dfs1(i); while(!S.empty()) { int Top=S.top(); S.pop(); if(!Belong[Top]) { Block++; dfs2(Top); } } for(int i=0; i<N; i++) if(Belong[2*i]==Belong[2*i+1]) return 0; return 1; } bool F(int p1,int p2,int f1,int f2) { double leftTop_p1_x,leftTop_p1_y; double rightBottom_p1_x,rightBottom_p1_y; double leftTop_p2_x,leftTop_p2_y; double rightBottom_p2_x,rightBottom_p2_y; if(f1==0) { leftTop_p1_x=p[p1].x-1.0*mid/2; leftTop_p1_y=p[p1].y; rightBottom_p1_x=p[p1].x+1.0*mid/2; rightBottom_p1_y=p[p1].y-mid; } else { leftTop_p1_x=p[p1].x-1.0*mid/2; leftTop_p1_y=p[p1].y+mid; rightBottom_p1_x=p[p1].x+1.0*mid/2; rightBottom_p1_y=p[p1].y; } if(f2==0) { leftTop_p2_x=p[p2].x-1.0*mid/2; leftTop_p2_y=p[p2].y; rightBottom_p2_x=p[p2].x+1.0*mid/2; rightBottom_p2_y=p[p2].y-mid; } else { leftTop_p2_x=p[p2].x-1.0*mid/2; leftTop_p2_y=p[p2].y+mid; rightBottom_p2_x=p[p2].x+1.0*mid/2; rightBottom_p2_y=p[p2].y; } if(leftTop_p1_x<leftTop_p2_x&&leftTop_p2_x<rightBottom_p1_x && rightBottom_p1_y<leftTop_p2_y&&leftTop_p2_y<leftTop_p1_y) return 1; if(leftTop_p1_x<leftTop_p2_x&&leftTop_p2_x<rightBottom_p1_x && rightBottom_p1_y<rightBottom_p2_y&&rightBottom_p2_y<leftTop_p1_y) return 1; if(leftTop_p1_x<rightBottom_p2_x&&rightBottom_p2_x<rightBottom_p1_x && rightBottom_p1_y<leftTop_p2_y&&leftTop_p2_y<leftTop_p1_y) return 1; if(leftTop_p1_x<rightBottom_p2_x&&rightBottom_p2_x<rightBottom_p1_x && rightBottom_p1_y<rightBottom_p2_y&&rightBottom_p2_y<leftTop_p1_y) return 1; if(leftTop_p2_x<leftTop_p1_x&&leftTop_p1_x<rightBottom_p2_x && rightBottom_p2_y<leftTop_p1_y&&leftTop_p1_y<leftTop_p2_y) return 1; if(leftTop_p2_x<leftTop_p1_x&&leftTop_p1_x<rightBottom_p2_x && rightBottom_p2_y<rightBottom_p1_y&&rightBottom_p1_y<leftTop_p2_y) return 1; if(leftTop_p2_x<rightBottom_p1_x&&rightBottom_p1_x<rightBottom_p2_x && rightBottom_p2_y<leftTop_p1_y&&leftTop_p1_y<leftTop_p2_y) return 1; if(leftTop_p2_x<rightBottom_p1_x&&rightBottom_p1_x<rightBottom_p2_x && rightBottom_p2_y<rightBottom_p1_y&&rightBottom_p1_y<leftTop_p2_y) return 1; if(leftTop_p1_x==leftTop_p2_x&&rightBottom_p1_x==rightBottom_p2_x) { if(rightBottom_p1_y<leftTop_p2_y&&leftTop_p2_y<leftTop_p1_y) return 1; if(rightBottom_p1_y<rightBottom_p2_y&&rightBottom_p2_y<leftTop_p1_y) return 1; if(rightBottom_p2_y<leftTop_p1_y&&leftTop_p1_y<leftTop_p2_y) return 1; if(rightBottom_p2_y<rightBottom_p1_y&&rightBottom_p1_y<leftTop_p2_y) return 1; } if(leftTop_p1_y==leftTop_p2_y&&rightBottom_p1_y==rightBottom_p2_y) { if(leftTop_p1_x<leftTop_p2_x&&leftTop_p2_x<rightBottom_p1_x) return 1; if(leftTop_p1_x<rightBottom_p2_x&&rightBottom_p2_x<rightBottom_p1_x) return 1; if(leftTop_p2_x<leftTop_p1_x&&leftTop_p1_x<rightBottom_p2_x) return 1; if(leftTop_p2_x<rightBottom_p1_x&&rightBottom_p1_x<rightBottom_p2_x) return 1; } if(leftTop_p1_x==leftTop_p2_x&&rightBottom_p1_x==rightBottom_p2_x) if(leftTop_p1_y==leftTop_p2_y&&rightBottom_p1_y==rightBottom_p2_y) return 1; return 0; } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d",&N); for(int i=0;i<N;i++) scanf("%lf%lf",&p[i].x,&p[i].y); left=0;right=50000; while(left<=right) { mid=(left+right)/2; init(); for(int i=0;i<N;i++) { for(int j=i+1;j<N;j++) { if(F(i,j,0,0)) {addEdge(2*i,2*j+1);addEdge(2*j,2*i+1);} if(F(i,j,0,1)) {addEdge(2*i,2*j);addEdge(2*j+1,2*i+1);} if(F(i,j,1,0)) {addEdge(2*i+1,2*j+1);addEdge(2*j,2*i);} if(F(i,j,1,1)) {addEdge(2*i+1,2*j);addEdge(2*j+1,2*i);} } } if(judge()) {ans=mid;left=mid+1;} else right=mid-1; } printf("%d\n",ans); } return 0; }