poj2296 Map Labeler(2-sat+二分)

由於每個點要麼在label的頂邊或者在label的底邊且在中間,並且有且只有一個在label上,所以就可以轉化爲2-sat問題。
建圖如下:
不妨設 點yi<=yj。(i表示向下,!i表示向上)
if(|xi-xj|>=d) continue;
if(yj-yi>=2*d) continue;
if(yj-ji>=d) i||!j
else if(yj-ji>0) i&&!j
else if(yj==yi) (i&&!j)||(j&&!i)即(!j||!i)&&(j||i)

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <stdlib.h>
#include <stack>
#include <vector>
#include <string.h>
#include <queue>
#define mabs(X) ((X)>0?(X):(-(X)))
#define msc(X) memset(X,-1,sizeof(X))
#define ms(X) memset(X,0,sizeof(X))
typedef long long LL;
using namespace std;
int m;
struct _Point
{
    int x,y;
}point[110];
int cmp(const void *a,const void *b)
{return ((struct _Point *)a)->y-((struct _Point *)b)->y;}
struct _Edge
{
    int to,next;
}edge[205*205];
int hd[205],tot;
void addedge(int u,int v)
{
    edge[tot].to=v;
    edge[tot].next=hd[u];
    hd[u]=tot++;
}
void inti(int d)
{
    tot=0;
    msc(hd);
    for(int i=0;i<m;i++)
        for(int j=i+1;j<m;j++)
        {
            if(mabs(point[i].x-point[j].x)>=d)
                continue;
            if(point[j].y-point[i].y>=2*d)
                continue;
            if(point[j].y-point[i].y>=d)
            {//  i||!j
                addedge(i<<1,j<<1);
                addedge(j<<1|1,i<<1|1);
            }
            else if(point[j].y-point[i].y>0)
            {//  i&&!j
                addedge(i<<1,i<<1|1);
                addedge(j<<1|1,j<<1);
            }
            else if(point[i].y==point[j].y)//注意
            {// (i&&!j)||(!i&&j)
                addedge(j<<1|1,i<<1);
                addedge(i<<1|1,j<<1);
                addedge(i<<1,j<<1|1);
                addedge(j<<1,i<<1|1);
            }
        }
}
int Low[205],DFN[205],Stack[205],Belong[205];
int Index,top;
int scc;
bool Instack[205];
void Tarjan(int u)
{
    int v;
    Low[u]=DFN[u]=++Index;
    Stack[top++]=u;
    Instack[u]=true;
    for(int i=hd[u];i!=-1;i=edge[i].next)
    {
        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];
            Belong[v]=scc;
            Instack[v]=false;
        }while(u!=v);
    }
}
bool judge(int d)
{
    inti(d);
    ms(DFN);
    ms(Instack);
    Index=scc=top=0;
    for(int i=0;i<2*m;i++)
        if(!DFN[i]) Tarjan(i);
    for(int i=0;i<m;i++)
        if(Belong[i<<1]==Belong[i<<1|1])
            return false;
    return true;
}
int main(int argc, char const *argv[])
{
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&m);
        for(int i=0;i<m;i++)
            scanf("%d %d",&point[i].x,&point[i].y);
        qsort(point,m,sizeof(struct _Point),cmp);
        int l=1,r=20005;
        while(l<r){
            int mid=(l+r)>>1;
            if(!judge(mid)) r=mid;
            else if(judge(mid+1)) l=mid+1;
            else {
                printf("%d\n",mid );
                break;
            }
        }
    }
    return 0;
}
發佈了110 篇原創文章 · 獲贊 3 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章