zoukankan      html  css  js  c++  java
  • 【HDU】3622 Bomb Game(2-SAT)

    http://acm.hdu.edu.cn/showproblem.php?pid=3622

    又是各种逗。。

    2-SAT是一种二元约束,每个点可以置于两种状态,但只能处于一种状态,然后图是否有解就是2-SAT啦。

    看白书吧。

    这个图的边的概念一定要弄懂!以下的x'表示x的另一个点

    边(x, y)表示取了x就一定取y,x是前提条件!

    对于约束(x, y),取x但不取y,那么显然连边(x, y'), (y, x'),这个意思一定要懂,就是说取了x就取y的另一个,可以唯一确定;那么反之取了y就一定取x的另一个(这里一定不是(x', y),因为x'是由y决定而不是y由x'决定)=

    upd:我不知道前边在说什么,,,其实很简单的,对于两个状态x和y,假设我们要满足(x=1 或 y=0),那么显然当x=0时要满足这个性质,那么y只能=0。反之亦然。所以就是连边x0->y0, y1->x1。这题也是同理,对于状态x和y,如果x1和y1不能撮合,那么就连边x0->y1, y0->x1,这是因为我们必须要满足取一个,即(x=1 或 y=1),至少取一个,那么当x=0时,就只能连y1,(当然不考虑x0和y1冲突,因为我们分两次建图。。。如果到最后冲突,说明无解)

    sigh..

    这篇博文讲得十分详细orz http://www.cnblogs.com/kuangbin/archive/2012/10/05/2712429.html

    白书上写的是dfs求,还有一种是tarjan缩点求。。

    我暂时写白书的。。

    本题只要二分半径然后连边即可。

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    using namespace std;
    #define rep(i, n) for(int i=0; i<(n); ++i)
    #define for1(i,a,n) for(int i=(a);i<=(n);++i)
    #define for2(i,a,n) for(int i=(a);i<(n);++i)
    #define for3(i,a,n) for(int i=(a);i>=(n);--i)
    #define for4(i,a,n) for(int i=(a);i>(n);--i)
    #define CC(i,a) memset(i,a,sizeof(i))
    #define read(a) a=getint()
    #define print(a) printf("%d", a)
    #define dbg(x) cout << (#x) << " = " << (x) << endl
    #define printarr2(a, b, c) for1(_, 1, b) { for1(__, 1, c) cout << a[_][__]; cout << endl; }
    #define printarr1(a, b) for1(_, 1, b) cout << a[_] << '	'; cout << endl
    inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
    inline const int max(const int &a, const int &b) { return a>b?a:b; }
    inline const int min(const int &a, const int &b) { return a<b?a:b; }
    
    const int N=215;
    const double eps=1e-4;
    int n, nn, x[N], y[N], vis[N], s[N], ihead[N], cnt, top;
    struct ED { int to, next; }e[(N*N)<<1];
    void add(int u, int v) { e[++cnt].next=ihead[u]; ihead[u]=cnt; e[cnt].to=v; }
    bool dfs(int u) {
    	if(vis[u]) return true;
    	if(vis[u^1]) return false;
    	vis[u]=true; s[++top]=u;
    	for(int i=ihead[u]; i; i=e[i].next) if(!dfs(e[i].to)) return false;
    	return true;
    }
    bool check(double r) {
    	CC(ihead, 0); cnt=0; CC(vis, 0);
    	double dis=(r*r)*4;
    	for1(i, 2, nn) {
    		int t; if(i&1) t=i+1; else t=i+2;
    		for1(j, t, nn) {
    			double x1=x[i], y1=y[i], x2=x[j], y2=y[j];
    			double rg=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
    			if(rg<dis) add(i, j^1), add(j, i^1);
    		}
    	}
    	for(int i=2; i<nn; i+=2) if(!vis[i] && !vis[i+1]) {
    		top=0;
    		if(!dfs(i)) {
    			while(top) vis[s[top--]]=0;
    			if(!dfs(i+1)) return false;
    		}
    	}
    	return true;
    }
    
    int main() {
    	while(~scanf("%d", &n)) {
    		for1(i, 1, n) rep(j, 2) read(x[(i<<1)+j]), read(y[(i<<1)+j]); nn=(n<<1)+1;
    		double l=0, r=50000;
    		while(r-l>eps) {
    			double m=(l+r)/2;
    			if(check(m)) l=m;
    			else r=m;
    		}
    		printf("%.2lf
    ", l);
    	}
    	return 0;
    }
    

    Problem Description
    Robbie is playing an interesting computer game. The game field is an unbounded 2-dimensional region. There are N rounds in the game. At each round, the computer will give Robbie two places, and Robbie should choose one of them to put a bomb. The explosion area of the bomb is a circle whose center is just the chosen place. Robbie can control the power of the bomb, that is, he can control the radius of each circle. A strange requirement is that there should be no common area for any two circles. The final score is the minimum radius of all the N circles.
    Robbie has cracked the game, and he has known all the candidate places of each round before the game starts. Now he wants to know the maximum score he can get with the optimal strategy.
     
    Input
    The first line of each test case is an integer N (2 <= N <= 100), indicating the number of rounds. Then N lines follow. The i-th line contains four integers x1i, y1i, x2i, y2i, indicating that the coordinates of the two candidate places of the i-th round are (x1i, y1i) and (x2i, y2i). All the coordinates are in the range [-10000, 10000].
     
    Output
    Output one float number for each test case, indicating the best possible score. The result should be rounded to two decimal places.
     
    Sample Input
    2 1 1 1 -1 -1 -1 -1 1 2 1 1 -1 -1 1 -1 -1 1
     
    Sample Output
    1.41 1.00
     
    Source
     
    Recommend
    lcy   |   We have carefully selected several similar problems for you:  3625 3628 3629 3627 3621
  • 相关阅读:
    spring获取webapplicationcontext,applicationcontext几种方法详解(转)
    spring注入是否会被回收
    think in java 手记(一)
    spring 注解实例
    navicat远程连接oracle
    tomcat监听activemq jms配置
    HDU 1160:FatMouse's Speed
    YTU 2457: 很简单的一道题
    YTU 2456: 评委打分
    YTU 2455: Pefect 数字
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/4003726.html
Copyright © 2011-2022 走看看