UVA11853(DFS)

来源:互联网 发布:男士去黑头洗面奶知乎 编辑:程序博客网 时间:2024/06/10 23:32

You are playing paintball on a 1000 × 1000 square field. A number of your opponents are on the field hiding behind trees at various positions. Each opponent can fire a paintball a certain distance in any direction. Can you cross the field without being hit by a paintball?
Assume that the southwest corner of the field is at (0, 0) and the northwest corner at (0,1000).
Input
The input contains several scenario. Each scenario consists of a line containing n ≤ 1000, the number of opponents. A line follows for each opponent, containing three real numbers: the (x,y) location of the opponent and its firing range. The opponent can hit you with a paintball if you ever pass within his firing range.
You must enter the field somewhere between the southwest and northwest corner and must leave somewhere between the southeast and northeast corners.
Output
For each scenario, if you can complete the trip, output four real numbers with two digits after the decimal place, the coordinates at which you may enter and leave the field, separated by spaces. If you can enter and leave at several places, give the most northerly. If there is no such pair of positions, print the line:‘IMPOSSIBLE’
Sample Input
3
500 500 499
0 0 999
1000 1000 200
Sample Output
0.00 1000.00 1000.00 800.00

其实很简单。搜索一下就好。和图论基本没半毛钱关系。
题意分析:
在一个1000*1000的方块场地中,你需要从最左边开始一路避开敌人的攻击到达最右边。敌人有自己的坐标以及攻击范围,也就是一个圆形范围内你都不能碰到,问你能到达最右边吗?能的话输出左边进入的最大坐标(0,Ymax), 右边出去的最大坐标(1000,Ymax)。
解题思路:
什么情况下不能到达目标呢?只有这种情况,也就是相邻的圆连接起来隔断了整个地图,否则都是可以到达的。这样的话,一个dfs直接判断就行了。剩下的是坐标怎么找到,首先默认最大坐标为(0,1000)和(1000,1000),什么时候不能从这个点出发呢?以最左边的进入点为例:如下图

此时,最高点,只能是红色点。可以发现,仅有这种从入点到其最上方都被挡住的情况,才会使得进入点下移。这样我们在dfs判断是否被隔断的时候,就可以顺手判断最高点位置了。

以上是http://blog.csdn.net/catglory/article/details/47999167的分析 写得很清楚 膜大神

#include "cstring"#include "cstdio"#include "string.h"#include "iostream"#include "cmath"#include "vector"#include "algorithm"#define exp 0.00001using namespace std;typedef struct node{    double x;    double y;    double range;}node;bool flag;double ans1;double ans2;node mmap[1005];bool mark[1005];vector<int> llist[1005];double dis(int i,int j){    double temp1=mmap[i].x-mmap[j].x;    double temp2=mmap[i].y-mmap[j].y;    return sqrt(temp1*temp1+temp2*temp2);}void dfs(int i){    if(flag||mark[i])        return;    mark[i]=1;    if(mmap[i].y<=mmap[i].range)    {        flag=1;return;    }    if(mmap[i].x+mmap[i].range>=1000)    {        ans2=min(ans2,mmap[i].y-sqrt(mmap[i].range*mmap[i].range-(1000-mmap[i].x)*(1000-mmap[i].x)));    }    if(mmap[i].x-mmap[i].range<=0)    {        ans1=min(ans1,mmap[i].y-sqrt(mmap[i].range*mmap[i].range-(mmap[i].x*mmap[i].x)));    }    for(int j=0;j<llist[i].size();j++)    {        dfs(llist[i][j]);    }}int main(){    int n;    while(scanf("%d",&n)!=EOF)    {        flag=0;        ans1=1000.0;        ans2=1000.0;        memset(mark,0,sizeof(mark));        for(int i=1;i<=n;i++)            llist[i].clear();        for(int i=1;i<=n;i++)            scanf("%lf%lf%lf",&mmap[i].x,&mmap[i].y,&mmap[i].range);        for(int i=1;i<=n;i++)        {            for(int j=i+1;j<=n;j++)            {                if(dis(i,j)<=mmap[i].range+mmap[j].range)                {                    llist[i].push_back(j);                    llist[j].push_back(i);                }            }        }        for(int i=1;i<=n;i++)        {            if(mmap[i].range+mmap[i].y>=1000)                dfs(i);        }        if(flag)            printf("IMPOSSIBLE\n");        else            printf("%.2f %.2f %.2f %.2f\n",0.0,ans1,1000.0,ans2);    }    return 0;}
0 0