SGU 198. Get Out! (计算几何+SPFA)

SGU198 题意就是一个圆形的船,然后有一些圆形的岛阻碍着船,问船能不能顺利出来。 做法就是把船的半径累加到岛中,这样只要判断 船的圆心,是否被一些圆包围。 可以使用SPFA去判断,有没有负环。

198. Get Out!

time limit per test: 0.25 sec. memory limit per test: 65536 KB

input: standard output: standard

Captain Faraway on his famous circular ship Kolobok is lost among the islands of the archipelago that he has just discovered. Now he wonders whether he can get out of there. Help him! All islands in the archipelago can be composed of pieces that have circular form. You are given the map of archipelago and the position of captain. Find out whether captain can get out of there, i.e. can get as far from the point he is in the beginning as he likes.

Input

The first line contains N — the number of circular island parts (1 ≤ N ≤ 300). N lines follow, each containing xi, yi, ri — coordinates of center and radius of the i-th circle. All coordinates and radii are real. Objects may overlap with each other in arbitrary way. All objects are considered solid. The last line of the input file contains three real numbers — coordinates of the center of Kolobok and its radius. You may consider Kolobok to be the perfect circle and that it is in the free area in the beginning. Kolobok can move along any trajectory and is so strong that he can even touch islands, but no nonzero part of island must intersect Kolobok during his motion. You may assume that making calculations with the precision of 10-6 is satisfactory.

Output

Output YES if Kolobok can leave archipelago and NO if it cannot.

Sample test(s)

Input

Test #1 7 2 2 1.1 -2 2 1.1 2 -2 1.0 -2 -2 1.0 2 -5 1.0 0 -8 1.0 -2 -6 1.0 0 0 1 Test #2 5 2 2 1.1 -2 2 1.1 2 -2 1.0 -2 -2 1.0 0 -3 0.01 0 0 1

Output

Test #1 YES Test #2 NO

/* ***
Author :kuangbin
Created Time :2014/11/10 20:16:21
File Name :D:\github\ACM-ICPC\SGU\SGU198.cpp
************************************************ */

#include <stdio.h>

#include <string.h>

#include

#include

#include

#include

#include

#include

#include

#include <math.h>

#include <stdlib.h>

#include <time.h>
using namespace std;
const double eps = 1e-8;
const int MAXN = 310;
struct Circle{
double x,y,r;
Circle(double _x = 0,double _y = 0,double _r = 0){
x = _x; y = _y; r = _r;
}
void input(){
scanf(“%lf%lf%lf”,&x,&y,&r);
}
bool check(Circle b){
double d = hypot(x-b.x,y-b.y);
return d < r + b.r - eps;
}
Circle operator -(const Circle &b)const{
return Circle(x-b.x,y-b.y,0);
}
double operator (const Circle &b)const{
return x\
b.x + y*b.y;
}
double operator ^(const Circle &b)const{
return x*b.y - y*b.x;
}
}circle[MAXN];
Circle p0;
double rad(Circle a,Circle b){
return atan2((a-p0)^(b-p0),(a-p0)*(b-p0));
}

struct Edge{
int to,next;
double w;
}edge[MAXN*MAXN];
int head[MAXN],tot;
void init(){
tot = 0;
memset(head,-1,sizeof(head));
}
inline void addedge(int u,int v,double w){
edge[tot].to = v;
edge[tot].w = w;
edge[tot].next = head[u];
head[u] = tot++;
}
double dist[MAXN];
bool vis[MAXN];
int cnt[MAXN];
bool SPFA(int n){
for(int i = 0;i < n;i++){
dist[i] = 0.0;
vis[i] = false;
cnt[i] = 0;
}
queueq;
for(int i = 0;i < n;i++){
vis[i] = true;
q.push(i);
cnt[i]++;
}
while(!q.empty()){
int u = q.front();
q.pop();
vis[u] = false;
for(int i = head[u];i != -1;i = edge[i].next){
int v = edge[i].to;
double w = edge[i].w;
if(dist[u] + w < dist[v] - eps){
dist[v] = dist[u] + w;
if(!vis[v]){
vis[v] = true;
cnt[v]++;
q.push(v);
if(cnt[v] > n)return false;
}
}
}
}
return true;
}

int main()
{
//freopen(“in.txt”,”r”,stdin);
//freopen(“out.txt”,”w”,stdout);
int n;
while(scanf(“%d”,&n) == 1){
for(int i = 0;i < n;i++)
circle[i].input();
p0.input();
for(int i = 0;i < n;i++)
circle[i].r += p0.r;
init();
for(int i = 0;i < n;i++)
for(int j = 0;j < n;j++)
if(i != j){
if(circle[i].check(circle[j]))
addedge(i,j,rad(circle[i],circle[j]));
}
if(SPFA(n))printf(“YES\n”);
else printf(“NO\n”);
}
return 0;
}

------ 本文结束------
  • 本文作者: kuangbin
  • 本文链接: 504.html
  • 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
0%