1. 程式人生 > >hdu 3622 Bomb Game(二分答案+2-sat判斷答案可行性)

hdu 3622 Bomb Game(二分答案+2-sat判斷答案可行性)

題目連結:

題目大意:

有n個炸彈,每個炸彈的放置位置有兩個可選,每個炸彈的爆炸範圍不能交叉,問我所有炸彈的中爆炸範圍最小的那個炸彈的爆炸範圍最大是多少

題目分析:

首先炸彈放置的位置是兩個,那麼就是2-sat問題,我們只需要二分答案,然後判斷答案是否合法,如果答案合法,那麼答案就可能是更大的值,每次二分出的mid值作為所有炸彈的爆炸範圍,如果他們能夠得到不會交叉的解,那麼說明當前方案可行,建邊的時候就是對於任意兩個點,列舉他們各自的兩個點是否會相交,如果會,那麼選其中一個就一定不選另一個

程式碼如下:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <stack>
#include <cmath>
#define MAX 207
#define eps 1e-9

using namespace std;

int mark[MAX],dfn[MAX],low[MAX],belong[MAX],times,cnt;
vector<int> e[MAX];
stack<int> s;

struct Point
{
    double x,y;
}p[MAX];

double dis ( Point a , Point b )
{
    return sqrt ((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
}

void tarjan ( int u )
{
    dfn[u] = low[u] = ++times;
    mark[u] = 1;
    s.push ( u );
    int len = e[u].size();
    for ( int i= 0 ; i < len ; i++ )
    {
        int v = e[u][i];
        if ( !mark[v] )
        {
            tarjan ( v );
            low[u] = min ( low[u] , low[v] );
        }
        if ( mark[v] == 1 )
            low[u] = min ( low[u] , dfn[v] );
    }
    if ( dfn[u] == low[u] )
    {
        int temp;
        do
        {
            temp = s.top();
            belong[temp] = cnt;
            mark[temp] = 2;
            s.pop();
        }while ( temp != u );
        cnt++;
    }
}

void init ( )
{
    memset ( mark , 0 , sizeof ( mark ));
    for ( int i = 0 ; i < MAX ; i++ )
        e[i].clear();
    while ( !s.empty() ) s.pop();
    times = cnt = 0;
}

int n,m;

bool check ( double mid )
{
    init();
    for ( int i = 0 ; i < n ; i++ )
        for ( int j = i+1 ; j < n ; j++ )
        {
            int x = i<<1 , y = j<<1;
            int u = i<<1|1 , v = j<<1|1;
            /*if ( dis( p[x] , p[y] ) + eps < mid && dis ( p[u] , p[v] ) + eps < mid
                 dis( p[u] , p[y] ) + eps < mid && dis ( p[x] , p[v] ) + eps < mid )
                    return false;*/
            if ( dis ( p[x] , p[y] ) + eps < mid*2 )
            {
                e[x].push_back( v );
                e[y].push_back( u );
            }
            if ( dis ( p[u] , p[v] ) + eps < mid*2 )
            {
                e[u].push_back ( y );
                e[v].push_back ( x );
            }
            if ( dis ( p[x] , p[v]) + eps < mid*2 )
            {
                e[x].push_back ( y );
                e[v].push_back ( u );
            }
            if ( dis ( p[u] , p[y] ) + eps < mid*2 )
            {
                e[u].push_back ( v );
                e[y].push_back ( x );
            }
        }

    for ( int i = 0 ; i < 2*n ; i++ )
        if ( !mark[i] ) tarjan ( i );

    for ( int i = 0 ; i < n ; i++ )
        if ( belong[i<<1] == belong[i<<1|1] )
            return false;
    return true;
}

int main ( )
{
    while ( ~scanf ( "%d" , &n ))
    {
        for ( int i = 0 ; i < n ; i++ )
            scanf ( "%lf%lf%lf%lf" , &p[i<<1].x , &p[i<<1].y , &p[i<<1|1].x , &p[i<<1|1].y );
        //cout << "YES" << endl;
        double l = 0 , r = 10000.0, mid;
        int times = 100;
        while ( times-- )
        {
            mid = ( l + r )/2.0;
            if ( check ( mid ) ) l = mid;
            else r = mid;
        }
        printf ( "%.2lf\n" , l );
    }
}


相關推薦

hdu 3622 Bomb Game(二分答案+2-sat判斷答案可行性)

題目連結: 題目大意: 有n個炸彈,每個炸彈的放置位置有兩個可選,每個炸彈的爆炸範圍不能交叉,問我所有炸彈的中爆炸範圍最小的那個炸彈的爆炸範圍最大是多少 題目分析: 首先炸彈放置的位置是兩個,那麼就是2-sat問題,我們只需要二分答案,然後判斷答案是否合法,如果答案合法,

HDU 3622 Bomb Game2-SAT 問題】

       題目大意:有N對點,給定這N對點的座標,現在要求找出一個最大的半徑R,使得可以從每對點中選擇一個點,並且這N個點以自己為圓心,半徑為R的圓兩兩不相交。        2-SAT問題解法:對於每一對點,我們且稱之為“兄弟點”;對於這2*N個點,如果兩個點之間“矛盾

HDU 3622 Bomb Game

題意:給你n個炸彈,每個炸彈都有兩個位置放置,問你最大的爆炸半徑,使得任意兩個炸彈的爆炸範圍不相交,可以相切,問半徑是多少 思路:對半徑進行二分,很顯然是單調的,所以滿足條件,然後由於點數不是很多,每次n2暴力建圖跑sat 程式碼:(忘記跑tarjan對著空氣debug半小時) #include

BZOJ4078 WF2014Metal Processing Plant(二分答案+2-SAT

  題面甚至沒給範圍,由資料可得n<=200。容易想到二分答案,暴力列舉某集合的價值,2-SATcheck一下即可。這樣是O(n4logn)的。   2-SAT複雜度已經是下界,考慮如何優化列舉。稍微改一下,不妨從大到小列舉較大的集合價值(即列舉邊),另一個集合二分答案,同樣O(n4logn)。  

HDU 4115 Eliminate the Conflict(2-sat)

not sof push space clear sans edi ali rgb HDU 4115 Eliminate the Conflict pid=41

Codeforces Round #400 (Div. 1 + Div. 2, combined) D. The Door Problem(二分染色?/2-sat,好題)

Moriarty has trapped n people in n distinct rooms in a hotel. Some rooms are locked, others are unlocked. But, there is a condition that the people in t

POJ 2749 Building roads 2-sat+二分答案

add set color head mem 多少 char size cto 把愛恨和最大距離視為限制條件,可以知道,最大距離和限制條件多少具有單調性 所以可以二分最大距離,加邊+check 1 #include<cstdio> 2 #include

2-Sat+二分_HDU 3622

題目意思是有n個選擇,每次都是隻能在兩個座標中選擇一個,然後再選擇的座標上畫圓,圓不能有重疊部分,問題畫的做大的面積是多少題中是兩個座標選一個,然後約束條件就是在當前半徑下兩個點畫圓是否有重疊,所以這是一個2-Sat問題,但是我們的半徑應該怎麼確定呢?很容易想打二分列舉就好#

HDU 1824 Let&#39;s go home (2-SAT判定)

記錄 arch 對數 ref ise stack top code any Let‘s go home Time Limit: 10000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe

UVALive3211- Now or later(二分+2-SAT)

print target gin ros 16px ng- arc can 變量 題目鏈接 題意:有n架飛機。每架飛機都能夠選擇早著陸和晚著陸兩種方式之中的一個,且必須選擇一種。任務就是安排全部飛機著陸時。相鄰兩個著陸時間間隔的最小值

HDU 3722 Card Game二分圖最佳完美匹配+KM算法)

思路 計算 pan style class hdu %d lan har 題目鏈接: http://acm.hdu.edu.cn/showproblem.php?pid=3722 1 /* 2 問題 3 將任意的兩個字符串進行匹配,使得匹配後權值和最大

poj2723 Get Luffy Out解題報告tarjan+2-SAT+二分

fine pan tor build push 若是 註意 ios ack 今天看到講2-SAT比較好的blog,感覺微微的理解了2-SAT 傳送門 參考: https://blog.csdn.net/leolin_/article/details/6680144 題意:你

HDU - 5884 Sort (二分答案+貪心)

sca 優先 scan n) empty 每次 都是 scanf light 有n個數字,你需要把這n個數字合成一個數字,每次只能把k個數字合並成一個,花費為這k個數字的和。 給一個最大花費,問不超過這個最大花費的情況下,k的最小值。 Sample Input 1

Get Luffy Out * HDU - 1816(2 - sat 媽的 智障)

freopen esp names clock int amp min pre ace 題意:   英語限制了我的行動力。。。。就是兩個鑰匙不能同時用,兩個鎖至少開一個 建個圖 二分就好了。。。emm。。。。dfs 開頭low 寫成sccno 然後生活失去希望。。。

Eliminate the Conflict HDU - 4115(2-sat 建圖 hhh)

ems clock memset void cloc define str mat sin 題意:   石頭剪刀布 分別為1、2、3,有n輪,給出了小A這n輪出什麽,然後m行,每行三個數a b k,如果k為0 表示小B必須在第a輪和第b輪的策略一樣,如果k為1 表示小B在第

HDU 1814 2-sat

Peaceful Commission Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5912 

hdu-1814(2-sat)

dfs div true max 方案 ostream ack %d ems 題意:給你n個組,m條規則,每組有倆個人,這兩個人不能同時出現,然後m條規則代表著有兩個人,這兩個人也不能同時出現,問你是否存在每組都能出現一人的選擇方案 解題思路:因為這個需要字典序輸出,所以只

hdu 3062 (2-sat

Description 有n對夫妻被邀請參加一個聚會,因為場地的問題,每對夫妻中只有1人可以列席。在2n 個人中,某些人之間有著很大的矛盾(當然夫妻之間是沒有矛盾的),有矛盾的2個人是不會同時出現在聚會上的。有沒有可能會有n 個人同時列席?

hdu 3062 Party【2-Sat】【經典入門】

Party Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 8219    Accepted Submiss

Codeforces Round #378 (Div. 2) D題(二分答案,貪心判斷

#include <cstdio> #include <cstring> #include <iostream> #include <algorithm>