zoukankan      html  css  js  c++  java
  • hdu3622(2SAT)

    题意:

    有N组炸弹,2*i与2*i+1为一组,从这N组炸弹中选N个炸弹放入格子中,

    要求:1.同组的炸弹不能同时放入;2.放入的炸弹不能相互引爆;3.每个炸弹有相同的半径;

    让你求半径里最短中最长的。

    思路:

    二分答案,用2-SAT判可行性。加边时,凡是可以互相引爆的两个点互斥。

    注意:

    对double型二分。引入eps.

    View Code
    /*
    Problem:3622 (Bomb Game) Judge Status:Accepted
    RunId:6286747 Language:G++ Author:2010201211
    Time:578MS Memory:2172K Len:3830B
    */
    #include <iostream>
    #include <stdio.h>
    #include <math.h>
    using namespace std;
    #include <string.h>
    #define E 1000050
    #define V 1000
    #define eps 1e-8
    double d[V][V];
    int n;
    double minc,maxc;
    struct Zu
    {
        double x1,y1,x2,y2;
    }zu[105];
    
    /******************2-SAT*********************/
    int top,cnt,index,ecnt;
    bool instack[V];
    int stack[V],id[V],dfn[V],low[V];
    int head[V];
    struct edge{
        int s,t,next;
    }e[E];
    void addedge(int u,int v){
        e[ecnt].s=u;
        e[ecnt].t=v;
        e[ecnt].next=head[u];
        head[u]=ecnt++;
    }
    void tarjan(int u){
        int v;
        int tmp;
        dfn[u]=low[u]=++index;
        instack[u]=true;
        stack[++top]=u;
        for(int k=head[u];k!=-1;k=e[k].next){
            v=e[k].t;
            if(!dfn[v]){
                tarjan(v);
                if(low[v]<low[u]){
                    low[u]=low[v];
                }
            }
            else if(instack[v] && dfn[v] < low[u]){
                low[u]=dfn[v];
            }
        }
        if(dfn[u]==low[u]){
            cnt++;
            do{
                tmp=stack[top--];
                instack[tmp]=false;
                id[tmp]=cnt;
            }while(tmp!=u);
        }
    }
    void solve(){
        top = cnt = index = 0;
        memset(dfn,0,sizeof(dfn));
        for(int i=0;i<2*n;i++){
            if(!dfn[i])
                tarjan(i);
        }
    }
    bool Two_Sat(){
        solve();
        for(int i=0;i<n;i++){
            if(id[i]==id[i+n]){
                return 0;
            }
        }
        return 1;
    }
    /******************2-SAT*********************/
    /*******************dist**********************/
    double dis(double x1,double y1,double x2,double y2){
        return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
    }
    void Count_dist(){
        minc=0x3F3F3F3F,maxc=-1;
        for(int i=0;i<n;i++){
            for(int j=0;j<i;j++){
                d[i][j]=d[j][i]=dis(zu[i].x1,zu[i].y1,zu[j].x1,zu[j].y1);
                minc=min(minc,d[i][j]);
                maxc=max(maxc,d[i][j]);
                d[i][j+n]=d[j+n][i]=dis(zu[i].x1,zu[i].y1,zu[j].x2,zu[j].y2);
                minc=min(minc,d[i][j+n]);
                maxc=max(maxc,d[i][j+n]);
                d[i+n][j]=d[j][i+n]=dis(zu[i].x2,zu[i].y2,zu[j].x1,zu[j].y1);
                minc=min(minc,d[i+n][j]);
                maxc=max(maxc,d[i+n][j]);
                d[i+n][j+n]=d[j+n][i+n]=dis(zu[i].x2,zu[i].y2,zu[j].x2,zu[j].y2);
                minc=min(minc,d[i+n][j+n]);
                maxc=max(maxc,d[i+n][j+n]);
            }
        }
    }
    /*******************dist**********************/
    /******************build**********************/
    bool build(double r){
        ecnt=0;
        memset(head,-1,sizeof(head));
        for(int i=0;i<n;i++){
            for(int j=i+1;j<n;j++){
                if(d[i][j]+eps<2*r){
                    addedge(i,j+n);
                    addedge(j,i+n);
                }
                if(d[i][j+n]+eps<2*r){
                    addedge(i,j);
                    addedge(j+n,i+n);
                }
                if(d[i+n][j]+eps<2*r){
                    addedge(i+n,j+n);
                    addedge(j,i);
                }
                if(d[i+n][j+n]+eps<2*r){
                    addedge(i+n,j);
                    addedge(j+n,i);
                }
            }
        }
        return Two_Sat();
    }
    /******************build**********************/
    /*************2-Search******************/
    void T_search(){
        double mid,l=-1,r=1000000,ans=0;
        while(r-l>=eps){
            mid=(l+r)/2.0;
            if(build(mid)){
                l=mid;
                ans=mid;
            }
            else
            {
                r=mid;
            }
        }
        printf("%.2lf\n",ans);
    }
    /*************2-Search******************/
    int main()
    {
        //freopen("in.txt","r",stdin);
        while(cin >> n){
            for(int i=0;i<n;i++){
                cin >> zu[i].x1 >> zu[i].y1 >> zu[i].x2 >> zu[i].y2;
            }
            Count_dist();
            T_search();
        }
        return 0;
    }
  • 相关阅读:
    Excel VB Script
    Excel Text Converter as C# Format
    快捷键
    如何使用 MasterPage
    Excel 오른쪽버튼 윗주
    Oracle Hints
    ASP.NET 弹出窗口
    Log4Net
    word 修改 表宽度
    While 나가는 법
  • 原文地址:https://www.cnblogs.com/markliu/p/2602286.html
Copyright © 2011-2022 走看看