hdu 2296 2-sat

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
using namespace std;

struct node
{
    int x,y;
}no[110];
int n;
struct edge
{
    int from,to,next;
}e[40010];
int ecnt;
int head[220];
void addedge(int from,int to)
{
    e[ecnt].from = from;
    e[ecnt].to = to;
    e[ecnt].next = head[from];
    head[from] = ecnt++;
}
int Maxl;
int abs(int a)
{
    return a > 0 ? a : -a;
}
int source(int i,int j,int r)
{
    if (abs(no[i].x - no[j].x) >= r || abs(no[i].y - no[j].y) >= 2*r)
    return 0;
    if (abs(no[i].y - no[j].y) < r )
    return 1;
    return 2;

}

void init(int r)
{
    memset(head,-1,sizeof(head));
    ecnt = 0;
    int tmp;
    int i,j;
    for(i=0;i<n;i++)
    for(j=i+1;j<n;j++)
    if( tmp = source(i,j,r) )
    {
        if ( tmp == 1 )
        {
            if (no[i].y == no[j].y)
            addedge(i*2,j*2+1),
            addedge(j*2,i*2+1),
            addedge(j*2+1,i*2),
            addedge(i*2+1,j*2);
            else if (no[i].y > no[j].y)
            addedge(i*2,i*2+1),
            addedge(j*2+1,j*2);
            else
            addedge(j*2,j*2+1),
            addedge(i*2+1,i*2);
        }
        else
        {
            if(no[i].y < no[j].y)
            addedge(i*2+1,j*2+1),
            addedge(j*2,i*2);
            else
            addedge(j*2+1,i*2+1),
            addedge(i*2,j*2);
        }
    }
}
int dfn[220],low[220],sta[220],belong[220],cnt,indexx,scnt;
bool instack[220];

void tarjan(int id)
{
    dfn[id] = low[id] = ++indexx;
    sta[scnt++] = id;
    instack[id] = true;
    int tmp;
    for(tmp=head[id];tmp!=-1;tmp=e[tmp].next)
    {
        if(!dfn[e[tmp].to])
        {
            tarjan(e[tmp].to);
            if(low[e[tmp].to] < low[id])
            low[id] = low[e[tmp].to];
        }else if( instack[e[tmp].to] && dfn[e[tmp].to] < low[id] )
        low[id] = dfn[e[tmp].to];
    }
    if(dfn[id]==low[id])
    {
        cnt++;
        while(1)
        {
            tmp = sta[--scnt];
            instack[tmp] = false;
            belong[tmp] = cnt;
            if(tmp==id) break;
        }
    }
}

bool search()
{
    int i,j;
    for(i=0;i<n;i++)
    if(belong[i*2]==belong[i*2+1])
    return false;
    return true;
}
int solve()
{
    int ans=0;
    int i,j;
    int l=0,r=20000;
    int Mid=(l+r)/2;
    while(r>=l)
    {
        init(Mid);
        indexx = scnt = cnt = 0;
        memset(dfn,0,sizeof(dfn));
        memset(instack,false,sizeof(instack));
        for(i=0;i<2*n;i++)
        if(!dfn[i])
        tarjan(i);
        if(search())
        ans=Mid,l = Mid+1;
        else
        r = Mid-1;
        Mid=(l+r)/2;
    }
    return ans;
}
int main()
{
    int t,i,j;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(i=0;i<n;i++)
        scanf("%d%d",&no[i].x,&no[i].y);
        printf("%d\n",solve());
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值