hdu3622 二分+2sat
来源:互联网 发布:mac的复制黏贴快捷键 编辑:程序博客网 时间:2024/05/16 11:34
题意:
给你N组炸弹,每组2个,让你在这N组里面选取N个放置,要求(1)每组只能也必须选取一个(2)炸弹与炸弹之间的半径相等(3)不能相互炸到对方。求最大的可放置半径。
思路:
给你N组炸弹,每组2个,让你在这N组里面选取N个放置,要求(1)每组只能也必须选取一个(2)炸弹与炸弹之间的半径相等(3)不能相互炸到对方。求最大的可放置半径。
思路:
二分去枚举半径,然后用2sat去判断是否可行,在2sat里,每组炸弹的两个是正常对,任何两组的任何两个距离小于等于mid那么这两个是矛盾对。这样强连通缩短,然后判断有没有一组是在同一个强连通块里的,没有那么就ok继续更新二分查找答案。
#include<stdio.h>#include<string.h>#include<math.h>#include<stack>#define N_node 200 + 10#define N_edge 100000 + 100using namespace std;typedef struct{ int to ,next;}STAR;typedef struct{ double x1 ,x2 ,y1 ,y2;}NODE;STAR E1[N_edge] ,E2[N_edge];NODE node[111];int list1[N_node] ,list2[N_node] ,tot;int Belong[N_node] ,cnt;int mark[N_node];stack<int>st;void add(int a , int b){ E1[++tot].to = b; E1[tot].next = list1[a]; list1[a] = tot; E2[tot].to = a; E2[tot].next = list2[b]; list2[b] = tot;}void DFS1(int s){ mark[s] = 1; for(int k = list1[s] ;k ;k = E1[k].next) { int xin = E1[k].to; if(!mark[xin]) DFS1(xin); } st.push(s);}void DFS2(int s){ mark[s] = 1; Belong[s] = cnt; for(int k = list2[s] ;k ;k = E2[k].next) { int xin = E2[k].to; if(!mark[xin]) DFS2(xin); }}double diss(double x1 ,double y1 ,double x2 ,double y2){ double tmp = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2); return sqrt(tmp);} bool ok(double mid ,int n){ memset(list1 ,0 ,sizeof(list1)); memset(list2 ,0 ,sizeof(list2)); tot = 1; for(int i = 0 ;i < n ;i ++) for(int j = i + 1 ;j < n ;j ++) { int a ,b; double dis = diss(node[i].x1 ,node[i].y1 ,node[j].x1 ,node[j].y1); if(dis <= mid) { a = i * 2 ,b = j * 2; add(a ,b^1) ,add(b ,a^1); } dis = diss(node[i].x1 ,node[i].y1 ,node[j].x2 ,node[j].y2); if(dis <= mid) { a = i * 2 ,b = j * 2 + 1; add(a ,b^1) ,add(b ,a^1); } dis = diss(node[i].x2 ,node[i].y2 ,node[j].x1 ,node[j].y1); if(dis <= mid) { a = i * 2 + 1,b = j * 2; add(a ,b^1) ,add(b ,a^1); } dis = diss(node[i].x2 ,node[i].y2 ,node[j].x2 ,node[j].y2); if(dis <= mid) { a = i * 2 + 1,b = j * 2 + 1; add(a ,b^1) ,add(b ,a^1); } } memset(mark ,0 ,sizeof(mark)); while(!st.empty())st.pop(); for(int i = 0 ;i < n * 2 ;i ++) if(!mark[i]) DFS1(i); memset(mark ,0 ,sizeof(mark)); cnt = 0; while(!st.empty()) { int xin = st.top(); st.pop(); if(mark[xin]) continue; ++cnt; DFS2(xin); } int mk = 0; for(int i = 0 ;i < n * 2 ;i += 2) { if(Belong[i] == Belong[i^1]) mk = 1; } return !mk;}int main (){ int n ,i; while(~scanf("%d" ,&n)) { for(i = 0 ;i < n ;i ++) scanf("%lf %lf %lf %lf" ,&node[i].x1 ,&node[i].y1 ,&node[i].x2 ,&node[i].y2); double low ,mid ,up ,ans = 0; low = 0 ,up = 2000000000; for(i = 1 ;i <= 100 ;i ++) { mid = (low + up) / 2; if(ok(mid ,n)) ans = low = mid; else up = mid; } printf("%.2lf\n" ,ans/2); } return 0;}
0 0
- HDU3622 二分+2-SAT
- HDU3622(二分+2-SAT)
- hdu3622 二分+2sat
- hdu3622 2-SAT+二分
- HDU3622 二分几何+2-SAT
- hdu3622(二分&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 2-sat问题,二分+判断有无解即可。
- [HDU3622][2-sat]Bomb Game
- HDU3622.Bomb Game——2-sat二分最大值+可行性判定
- [HDU3622]Bomb Game(2-SAT)
- [2-sat]动态的2-sat问题(hdu3622)
- hdu3622 Bomb Game(2分答案+2sat判定)
- HDU3622 Bomb Game(2-SAT 问题,The 35th ACM/ICPC Asia Regional Tianjin ,Online)
- StringUtils的isBlank与isEmply
- 算法导论习题解-第15章动态规划
- crond——Linux下的计划任务学习笔记
- jquery实现最简单焦点图切换
- C# 实现冒泡算法
- hdu3622 二分+2sat
- mac 终端 svn 命令
- spring定时器的实现方式-quartz 实现方式
- 唯快不破!90后大学生9天完成近670页的Swift语言文档翻译
- Linux声卡驱动移植和测试
- 找大数问题
- Nginx 的安装入门
- Android 自定义的数字键盘 支持随意拖动 和稳定的字符输入的控件
- C#不重启程序读取appconfig