ZOJ 3717 Balloon

_(:3」∠)_

就是很裸的一道2-SAT问题,比赛的时候忘记加同一对里的边,也没注意到最后的进位问题,所以搓了。

计算所有点之间的距离,排序后二分建图,二分的判断条件就是2-SAT。

#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#include<iostream>
#include<cmath>
using namespace std;

const int N=410;

struct Point
{
    int x,y,z;
}point[N];

struct Dis
{
    int dis,x,y;
}d[N*N];

int n,dlen;

vector<int> G[N<<1];
bool mark[N<<1];
int s[N<<1],cnt;

bool DFS(int x)
{
    if(mark[x^1]) return false;
    if(mark[x]) return true;
    mark[x]=true;
    s[cnt++]=x;
    for(int i=0;i<G[x].size();++i)
        if(!DFS(G[x][i])) return false;
    return true;
}

bool solve()
{
    for(int i=2;i<=n*2;i+=2) {
        if(!mark[i]&&!mark[i+1]) {
            cnt=0;
            if(!DFS(i)) {
                while(cnt) mark[s[--cnt]]=false;
                if(!DFS(i+1)) return false;
            }
        }
    }
    return true;
}

int dist(int i,int j)
{
    return (point[i].x-point[j].x)*(point[i].x-point[j].x)+
            (point[i].y-point[j].y)*(point[i].y-point[j].y)+
            (point[i].z-point[j].z)*(point[i].z-point[j].z);
}

bool cmp(Dis A,Dis B)
{
    return A.dis<B.dis;
}

void init()
{
    for(int i=0;i<=n*2;++i)
        G[i].clear();
    memset(mark,false,sizeof mark);
}

bool judge(int mid)
{
    int x,y;
    init();
    int t=n/2;
    for(int i=1;i<=t;++i) {
        x=i*2;
        y=(t+i)*2;
        G[x].push_back(y^1);
        G[y].push_back(x^1);
    }
    for(int i=0;i<mid;++i) {
        x=d[i].x;
        y=d[i].y;
        x*=2;
        y*=2;
        G[x^1].push_back(y);
        G[y^1].push_back(x);
    }
    return solve();
}

int main()
{
    int x,y;
    bool flag;
    int ans,np;
    int L,R,mid;
    double hehe;
    while(scanf("%d",&n)==1) {
        init();
        dlen=0;
        for(int i=1;i<=n;++i) {
            scanf("%d%d%d%d%d%d",&point[i].x,&point[i].y,&point[i].z,
                  &point[i+n].x,&point[i+n].y,&point[i+n].z);
        }
        n*=2;
        for(int i=1;i<=n;++i) {
            for(int j=i+1;j<=n;++j) {
                d[dlen].x=i;
                d[dlen].y=j;
                d[dlen++].dis=dist(i,j);
            }
        }
        sort(d,d+dlen,cmp);
        ans=d[0].dis;
        np=0;
        L=0,R=dlen-1;
        while(L<=R) {
            mid=L+(R-L)/2;
            if(judge(mid)) {
                L=mid+1;
                ans=d[mid].dis;
            }
            else R=mid-1;
        }
        hehe=sqrt(double(ans))/2;
        printf("%.3lf
",(int)(hehe*1000)/1000.0);
    }
}