zoukankan      html  css  js  c++  java
  • HDU 3622 Bomb Game 二分+2-SAT

    二分爆炸半径R,判断是否可行,如果可行,半径可以继续增加。

    之前建图有误,结果一直不对。

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <vector>
    
    using namespace std;
    
    const int MAXN = 222;
    const double eps = 1e-5;
    
    struct Point
    {
        double x, y;
        Point( double x = 0.0, double y = 0.0 ): x(x), y(y) { }
        void readPoint()
        {
            scanf( "%lf%lf", &x, &y );
            return;
        }
    };
    
    struct TwoSAT
    {
        int n;
        vector<int> G[ MAXN << 1 ];
        bool mark[MAXN << 1];
        int S[MAXN << 1], top;
    
        bool DFS( int x )
        {
            if ( mark[x^1] ) return false;
            if ( mark[x] )   return true;
            mark[x] = true;
            S[ ++top ] = x;
            int sz = G[x].size();
            for ( int i = 0; i < sz; ++i )
                if ( !DFS( G[x][i] ) ) return false;
            return true;
        }
    
        void init( int n )
        {
            this->n = n;
            for ( int i = 0; i < (n*2); ++i ) G[i].clear();
            memset( mark, false, sizeof(mark) );
            return;
        }
    
        void add_clause( int x, int xval, int y, int yval )
        {
            x = x * 2 + xval;
            y = y * 2 + yval;
            G[x^1].push_back(y);
            G[y^1].push_back(x);
            return;
        }
    
        bool solved()
        {
            for ( int i = 0; i < ( n * 2 ); i += 2 )
                if ( !mark[i] && !mark[i + 1] )
                {
                    top = 0;
                    if( !DFS(i) )
                    {
                        while ( top > 0 ) mark[ S[top--] ] = false;
                        if ( !DFS(i + 1) ) return false;
                    }
                }
            return true;
        }
    };
    
    int N;
    Point P[MAXN][2];
    TwoSAT Graph;
    double dist[110][2][110][2];
    
    double dcmp( double a )
    {
        if ( fabs(a) < eps ) return 0;
        return a < 0 ? -1 : 1;
    }
    
    double dis( Point a, Point b )
    {
        return sqrt( (a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y) );
    }
    
    bool check( double mid )
    {
        Graph.init( N );
        mid *= 2.0;
        for ( int i = 0; i < N; ++i )
            for ( int a = 0; a < 2; ++a )
                for ( int j = i + 1; j < N; ++j )
                    for ( int b = 0; b < 2; ++b )
                    {
                        if ( dcmp( dist[i][a][j][b] - mid ) < 0 )
                        {
                            Graph.add_clause( i, a ^ 1, j,  b ^ 1 );
                        }
                    }
    
        return Graph.solved();
    }
    
    int main()
    {
        while ( scanf( "%d", &N ) == 1 )
        {
            for ( int i = 0; i < N; ++i )
            {
                P[i][0].readPoint();
                P[i][1].readPoint();
            }
    
            for ( int i = 0; i < N; ++i )
                for ( int a = 0; a < 2; ++a )
                    for ( int j = i + 1; j < N; ++j )
                        for ( int b = 0; b < 2; ++b )
                            dist[i][a][j][b] = dist[j][b][i][a] = dis( P[i][a], P[j][b] );
    
            double l = 0.0, r = dis( Point( -10000.0, -10000.0 ), Point( 10000.0, 10000.0 ) );
            double mid, ans;
            while ( r - l > eps )
            {
                mid = ( l + r ) / 2.0;
                if ( check(mid) )
                {
                    ans = mid;
                    l = mid;
                    //printf( "mid = %.2f
    ", mid );
                }
                else r = mid;
            }
    
            printf( "%.2f
    ", ans );
        }
        return 0;
    }
  • 相关阅读:
    对于Spring使用注解的一点总结
    2014-01-12
    Struts2补充a
    2014从Struts2开始
    总结:XHTML中链接CSS的四种方法(笔记)
    XHTML
    我Web前端开发的开端
    踏上前端路
    调取手机相册和拍照功能js
    mac常用系统指令和终端指令总结
  • 原文地址:https://www.cnblogs.com/GBRgbr/p/3297722.html
Copyright © 2011-2022 走看看