博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU3622(二分+2-SAT)
阅读量:4605 次
发布时间:2019-06-09

本文共 4428 字,大约阅读时间需要 14 分钟。

Bomb Game

Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 5647    Accepted Submission(s): 2036

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 x
1i, y
1i, x
2i, y
2i, indicating that the coordinates of the two candidate places of the i-th round are (x
1i, y
1i) and (x
2i, y
2i). 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

 
题意:每次给出两个点,选其中一点为圆心画圆,半径任意。n次以后,画了n个圆,要求任意两个圆不能相交,问最小圆的半径最大为多少。
思路:二分最小圆的半径。
     check方法:若a点和b点的距离小于2×半径,NOT a和b连边,NOT b和a连边。
         建图完毕后,强连通分量分解,2-SAT判断是否可行。
1 //2017-08-27  2 #include 
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 10 using namespace std; 11 12 const int N = 5010; 13 const int M = N*N; 14 const double EPS = 1e-6; 15 int head[N], rhead[N], tot, rtot; 16 struct Edge{ 17 int to, next; 18 }edge[M], redge[M]; 19 20 void init(){ 21 tot = 0; 22 rtot = 0; 23 memset(head, -1, sizeof(head)); 24 memset(rhead, -1, sizeof(rhead)); 25 } 26 27 void add_edge(int u, int v){ 28 edge[tot].to = v; 29 edge[tot].next = head[u]; 30 head[u] = tot++; 31 32 redge[rtot].to = u; 33 redge[rtot].next = rhead[v]; 34 rhead[v] = rtot++; 35 } 36 37 vector
vs;//后序遍历顺序的顶点列表 38 bool vis[N]; 39 int cmp[N];//所属强连通分量的拓扑序 40 41 //input: u 顶点 42 //output: vs 后序遍历顺序的顶点列表 43 void dfs(int u){ 44 vis[u] = true; 45 for(int i = head[u]; i != -1; i = edge[i].next){ 46 int v = edge[i].to; 47 if(!vis[v]) 48 dfs(v); 49 } 50 vs.push_back(u); 51 } 52 53 //input: u 顶点编号; k 拓扑序号 54 //output: cmp[] 强连通分量拓扑序 55 void rdfs(int u, int k){ 56 vis[u] = true; 57 cmp[u] = k; 58 for(int i = rhead[u]; i != -1; i = redge[i].next){ 59 int v = redge[i].to; 60 if(!vis[v]) 61 rdfs(v, k); 62 } 63 } 64 65 //Strongly Connected Component 强连通分量 66 //input: n 顶点个数 67 //output: k 强连通分量数; 68 int scc(int n){ 69 memset(vis, 0, sizeof(vis)); 70 vs.clear(); 71 for(int u = 0; u < n; u++) 72 if(!vis[u]) 73 dfs(u); 74 int k = 0; 75 memset(vis, 0, sizeof(vis)); 76 for(int i = vs.size()-1; i >= 0; i--) 77 if(!vis[vs[i]]) 78 rdfs(vs[i], k++); 79 return k; 80 } 81 82 int n; 83 struct Point{ 84 int x, y; 85 }point[N]; 86 87 //input: 两个点 88 //output: 两点间距离 89 double distance(Point a, Point b){ 90 return sqrt((double)(a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y)); 91 } 92 93 //input:radius 半径 94 //output:true 通过选取某些点可以得到radius的分数,false 无法得到radius的分数 95 bool check(double radius){ 96 init(); 97 for(int i = 0; i < 2*n; i++){ 98 for(int j = i+1; j < 2*n; j++){ 99 if((i^1) == j)continue;100 if(distance(point[i], point[j]) < 2*radius){ //i与j存在矛盾101 add_edge(i^1, j);// NOT i -> j102 add_edge(j^1, i);// NOT j -> i103 }104 }105 }106 scc(2*n);107 for(int i = 0; i < 2*n; i += 2){108 if(cmp[i] == cmp[i^1])109 return false;110 }111 return true;112 }113 114 int main()115 {116 std::ios::sync_with_stdio(false);117 //freopen("inputC.txt", "r", stdin);118 while(cin>>n){119 for(int i = 0; i < n; i++){120 cin>>point[2*i].x>>point[2*i].y>>point[2*i+1].x>>point[2*i+1].y;121 }122 double l = 0.0, r = 40000.0, mid, ans = 0;123 while(r-l > EPS){124 mid = (l+r)/2;125 if(check(mid)){126 ans = mid;127 l = mid;128 }else129 r = mid;130 }131 cout.setf(ios::fixed);132 cout<
<
<

 

转载于:https://www.cnblogs.com/Penn000/p/7440437.html

你可能感兴趣的文章
一语道破项目管理知识体系五大过程组
查看>>
C# 备份、还原、拷贝远程文件夹
查看>>
在windows环境下运行compass文件出现的错误提示解决方案
查看>>
CSS常用样式--font
查看>>
恩如氏--蜗牛精华补水蚕丝面膜
查看>>
大工具-收藏
查看>>
codevs3027 线段覆盖 2
查看>>
markdown
查看>>
【leetcode】107-Binary Tree Level Order Traversal II
查看>>
Jquert data方法获取不到数据,显示为undefined。
查看>>
ssm项目中 数据库和资源的备份
查看>>
hdoj5671 BestCoder Round #81 (div.2)
查看>>
HDU5950【矩阵快速幂】
查看>>
在线C++编译器
查看>>
C#中各种serialization的比较
查看>>
P2617 Dynamic Rankings
查看>>
工作学习常识1
查看>>
github开发
查看>>
Emacs学习笔记(13):在Emacs中打开pdf
查看>>
flask模板应用-空白控制 --
查看>>