zoukankan      html  css  js  c++  java
  • zoj 3717 Balloon 2-sat

    题目:给出空间中的n对点,要求从每对点中选出一个,使得最近的点的距离最远。

    分析:

      二分的思想很明显,二分答案之后,建图:如果两点之间的距离小于二分值时,连接相应的边,通过2-sat判断一下即可。

      注意到题目的要求是向下取整,于是我们可以先*10000,最后直接取模即可。

    #include <set>
    #include <map>
    #include <list>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    typedef long long ll;
    typedef unsigned long long ull;
    
    #define debug puts("here")
    #define rep(i,n) for(int i=0;i<n;i++)
    #define rep1(i,n) for(int i=1;i<=n;i++)
    #define REP(i,a,b) for(int i=a;i<=b;i++)
    #define foreach(i,vec) for(unsigned i=0;i<vec.size();i++)
    #define pb push_back
    #define RD(n) scanf("%d",&n)
    #define RD2(x,y) scanf("%d%d",&x,&y)
    #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define RD4(x,y,z,w) scanf("%d%d%d%d",&x,&y,&z,&w)
    #define All(vec) vec.begin(),vec.end()
    #define MP make_pair
    #define PII pair<int,int>
    #define PQ priority_queue
    #define cmax(x,y) x = max(x,y)
    #define cmin(x,y) x = min(x,y)
    #define Clear(x) memset(x,0,sizeof(x))
    
    /******** program ********************/
    const int MAXN = 405;
    const int MAXM = 1000005;
    
    int low[MAXN],sta[MAXN],dfn[MAXN],fa[MAXN],dep,bcnt,top;
    bool use[MAXN];
    int po[MAXN],tol,n,m;
    
    struct Edge {
        int y,next;
    } edge[MAXM];
    
    struct Point {
        int a[3];
        void rd() {
            RD3(a[0],a[1],a[2]);
            a[0] *= 10000;
            a[1] *= 10000;
            a[2] *= 10000;
        }
    } p[MAXN][2];
    
    void add(int x,int y) {
        edge[++tol].y = y;
        edge[tol].next = po[x];
        po[x] = tol;
    }
    
    void dfs(int x) {
        sta[++top] = x;
        use[x] = true;
        low[x] = dfn[x] = ++ dep;
        int y;
        for(int i=po[x]; i; i=edge[i].next) {
            y = edge[i].y;
            if(!dfn[y]) {
                dfs(y);
                low[x] = min(low[x],low[y]);
            } else if(use[y])
                low[x] = min(low[x],dfn[y]);
        }
        if(low[x]==dfn[x]) {
            ++ bcnt;
            do {
                y = sta[top--];
                use[y] = false;
                fa[y] = bcnt;
            } while(x!=y);
        }
    }
    
    bool sat() {
        memset(dfn,0,sizeof(dfn));
        memset(use,false,sizeof(use));
        dep = top = bcnt = 0;
        rep1(i,2*n)
        if(!dfn[i])
            dfs(i);
        rep1(i,n)
        if(fa[i]==fa[i+n])
            return false;
        return true;
    }
    
    ll sqr(ll x) {
        return x*x;
    }
    
    ll dist(Point a,Point b) {
        return sqr(a.a[0]-b.a[0])+sqr(a.a[1]-b.a[1])+sqr(a.a[2]-b.a[2]);
    }
    
    bool solve(ll mid) {
        memset(po,0,sizeof(po));
        tol = 0;
        rep1(i,n) {
            rep1(j,n) {
                if(i==j)continue;
                ll d = dist(p[i][0],p[j][0]);
                if(d<mid) {
                    add(i,j+n);
                    add(j,i+n);
                }
    
                d = dist(p[i][0],p[j][1]);
                if(d<mid) {
                    add(i,j);
                    add(j+n,i+n);
                }
    
                d = dist(p[i][1],p[j][0]);
                if(d<mid) {
                    add(i+n,j+n);
                    add(j,i);
                }
    
                d = dist(p[i][1],p[j][1]);
                if(d<mid) {
                    add(i+n,j);
                    add(j+n,i);
                }
            }
        }
        return sat();
    }
    
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("sum.in", "r", stdin);
        // freopen("cf.out", "w", stdout);
    #endif
    
        while(~RD(n)) {
            rep1(i,n) {
                p[i][0].rd();
                p[i][1].rd();
            }
            ll ans = -1 , l = 0 , r = 2000000000LL;
            while(l<=r) {
                ll mid = (l+r)/2;
                if(solve(mid*mid)) {
                    l = mid+1;
                    ans = mid;
                } else r = mid-1;
            }
            printf("%lld.%03lld
    ",ans/20000,(ans/2%10000)/10 );
        }
    
        return 0;
    }
    

      

  • 相关阅读:
    JS 缓存
    时区转换
    JQuery easy UI 通过updateRow 排序
    SqlServer2008 数据库同步的两种方式
    C#各种辅助类收集(CSharpCommonHelper)
    Doc命令收集(一)
    Sql Server Alter语句
    JQuery easy UI updateRow
    Doc命令收集(二)
    六大开源搜索引擎工具
  • 原文地址:https://www.cnblogs.com/yejinru/p/3328703.html
Copyright © 2011-2022 走看看