zoukankan      html  css  js  c++  java
  • 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);
        }
    }
  • 相关阅读:
    php的语句
    php
    git分支
    git安装及git命令的用法
    git命令
    dos命令及github介绍
    无缝轮播的案例 及css3无缝轮播案例
    ACWING 031 表示数值的字符串
    Acwing 282. 石子合并 区间dp
    Leetcode 841. 钥匙和房间 dfs bfs
  • 原文地址:https://www.cnblogs.com/morimiya/p/3632869.html
Copyright © 2011-2022 走看看