[2-sat]动态的2-sat问题(hdu3622)
来源:互联网 发布:淘宝店刷销量多少钱 编辑:程序博客网 时间:2024/05/16 06:58
概述
在一些最优化的问题当中,我们不知道一些指标的最优值是多少,而这个指标又在影响我们的逻辑表达式,我觉得这样的问题是一种动态的2-sat问题。通常,我们使用搜索,不断的重复建图,最后达到解题的目标。
一个例题
这是ACM亚洲区比赛的一题:
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.
我们的思路:
显然,这是一个最优化的问题,每一步的两个点,我们只可以选一个,就好像一个逻辑变量一样。但是,我们该怎样构建逻辑表达式,也就是如何建图呢?很显然,这个我们所规定的最大半径有关,如果两个点间的距离小于我们所要求的半径,那么两个圆就是存在重叠面积的,这样的话两个点就不可以被同时选择。
二分搜索半径的大小,并且不断建图判断逻辑表达式的可解性,最后可以得到最优解。
不过这题最难的是精度啊。。。
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<stack>#include<queue>#include<cmath>using namespace std;#define MAXN 205#define MAXM 405#define ZERO 10e-5struct CPoint{ double x,y;}PointList[MAXN];struct Edge{ int to; int next;}EdgeTable[MAXN*MAXN];int head[MAXN];int dfn[MAXN],low[MAXN],match[MAXN];int state[MAXN];int e,n,cnt,curT;stack<int>S;double O_dis(CPoint a,CPoint b){ return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}void addEdge(int from,int to){ EdgeTable[e].to=to; EdgeTable[e].next=head[from]; head[from]=e++;}void get_Graph(double num){ int i,j; memset(head,-1,sizeof(head)); e=0; for(i=0;i<n;i++){ for(j=i+1;j<n;j++){ //the points in the same round should not be compared if(O_dis(PointList[2*i],PointList[2*j])-2*num<-ZERO){ addEdge(2*i,2*j+1); addEdge(2*j,2*i+1); } if(O_dis(PointList[2*i],PointList[2*j+1])-2*num<-ZERO){ addEdge(2*i,2*j); addEdge(2*j+1,2*i+1); } if(O_dis(PointList[2*i+1],PointList[2*j])-2*num<-ZERO){ addEdge(2*i+1,2*j+1); addEdge(2*j,2*i); } if(O_dis(PointList[2*i+1],PointList[2*j+1])-2*num<-ZERO){ addEdge(2*i+1,2*j); addEdge(2*j+1,2*i); } } } return;}void Dfs(int cur){ low[cur]=dfn[cur]=curT++; state[cur]=1; S.push(cur); int i; for(i=head[cur];i!=-1;i=EdgeTable[i].next){ int dest = EdgeTable[i].to; if(!state[dest]){ Dfs(dest); low[cur] = min(low[cur],low[dest]); } else if(state[dest]==1) low[cur] = min(low[dest],low[cur]); } if(low[cur]==dfn[cur]){ while(!S.empty()){ int d = S.top(); S.pop(); match[d]=cnt; state[d]=2; if(d==cur)break; } cnt++; } return;}bool Solve(){ memset(state,0,sizeof(state)); cnt=0; int i; for(i=0;i<2*n;i++){ if(!state[i]){ curT=0; Dfs(i); } } for(i=0;i<n;i++){ if(match[2*i]==match[2*i+1]) return false; } return true;}int main(){ freopen("input","r",stdin); int i,j; double maxdis; while(scanf("%d",&n)!=EOF){ maxdis=-1.0; for(i=0;i<2*n;i++){ scanf("%lf %lf",&PointList[i].x,&PointList[i].y); for(j=i-1;j>=0;j--) maxdis=max(maxdis,O_dis(PointList[i],PointList[j])); } double L=0.0,R=maxdis+0.1,ans=0.0; while((R-L)>=ZERO){ //apply binary search to find answer double mid=(L+R)/2; get_Graph(mid); //printf("%.2lf\n",mid); if(Solve()){ L=mid+ZERO; ans=mid; } else R=mid-ZERO; } printf("%.2f\n",ans); } return 0;}
- [2-sat]动态的2-sat问题(hdu3622)
- HDU3622 二分+2-SAT
- HDU3622(二分+2-SAT)
- hdu3622 二分+2sat
- hdu3622 2-SAT+二分
- [HDU3622][2-sat]Bomb Game
- HDU3622 二分几何+2-SAT
- hdu3622(二分&2-sat)
- hdu3622 2-sat问题,二分+判断有无解即可。
- hdu3622 Bomb Game(二分+2-SAT)
- HDU3622-Bomb Game(2-SAT+二分)
- hdu3622 Bomb Game--2-sat & 二分
- [HDU3622]Bomb Game(2-SAT)
- [二分 + 2-SAT] HDU3622: Bomb Game
- 【HDU3622】Bomb Game-二分答案+2-SAT
- HDU3622 Bomb Game(2-SAT 问题,The 35th ACM/ICPC Asia Regional Tianjin ,Online)
- hdu3622 Bomb Game(2分答案+2sat判定)
- 【2-SAT】2sat问题小结
- zypper命令使用及zypper源配置
- Ubuntu 14.04 英文版安装中文输入法
- MavenHelloWorld
- 【hdu 5800】To My Girlfriend dp+乱搞+总结
- C语言(四)指针概念的理解
- [2-sat]动态的2-sat问题(hdu3622)
- Windows环境下MinGW配置GCC编译环境的方法
- 电脑缺少msvcr120.dll文件 怎么弄
- js监听浏览器刷新或者关闭 window.onbeforeunload
- matplotlib 绘图-barChart
- c++的boost库多线程(Thread)编程(线程操作,互斥体mutex,条件变量)详解
- 【lightoj1043】几何数学
- 测试
- 第1部分 接口型模式