POJ-2588(snakes,抽象成图结构)

【转载思想】

题目意思就不说了,这里主要说一下做法!

我们把蛇连同它的攻击范围看做一个圆,再把圆抽象成一个点!点与点之间有边连接仅当两个点代表的圆有公共面积!然后我们在把上边界和下边界各抽象成一个点(S和T),同样上边界与点之间有边连接仅当点代表的圆与上边界相交,同理,可得下边界与点之间的边关系!

这样处理以后如果有从左到右的路径,当且仅当不存在S到T通路!只要深搜或者广搜即可!但是题目还要我们求出左右的坐标,只需确定纵坐标即可,而且纵坐标要最大!所以我们考虑与S连通的每一个点,如果该点代表的圆与左边界有交点,那么如果从这个交点上面走一定走不过去,所以我们更新左边的纵坐标到这个交点处,对所有的圆都这样处理,即可确定左边纵坐标,右边的同理可求!而且这一步可以在求连通的时候随便求出,我们只需从S出发,一直搜即可!

ps:只能在SOJ上AC,不能再POJ上AC

struct point
{
    int x, y;
    int r;
    double left;
    double right;
} wo[1005];
int g[1005][1005];
int ans;
int n;
int flag[1005] = {0};
void dfs(int s)
{
    if (flag[s] == 1) return ;
    if (s == n + 1) {
        ans = 1;
        return ;
    }
    flag[s] = 1;
    int i;
    for (i = 0; i < n + 2; ++i) {
        if (s == i) continue;
        if (g[s][i] == 1) {
            dfs(i);
        }
    }
}
int main()
{
    while (scanf("%d", &n) == 1) {
        memset(g, 0, sizeof(g));
        memset(flag, 0, sizeof(flag));
        memset(wo, 0, sizeof(wo));
        int i, j;
        for (i = 0; i < n; ++i)
            scanf("%d%d%d", &wo[i].x, &wo[i].y, &wo[i].r);
        int up = n;
        int down = n + 1; 
        for (i = 0; i < n; ++i) {
            if (wo[i].x <= wo[i].r) {
                wo[i].left = wo[i].x - sqrt(1.0 * wo[i].r * wo[i].r - wo[i].y * wo[i].y);
            } else {
                wo[i].left = -1;
            }
            if (1000 - wo[i].x <= wo[i].r) {
                wo[i].right = wo[i].x - sqrt(1.0 * wo[i].r * wo[i].r - (1000 - wo[i].y) * (1000 - wo[i].y));
            } else {
                wo[i].right = -1;
            }
            if (1000 - wo[i].y <= wo[i].r) {
                g[up][i] = g[i][up] = 1;
            }
            if (wo[i].y <= wo[i].r) {
                g[down][i] = g[i][down] = 1;
            }
            for (j = 0; j < n; ++j) {
                if (j != i) {
                    if ((wo[i].x - wo[j].x) * (wo[i].x - wo[j].x) + (wo[i].y - wo[j].y) * (wo[i].y - wo[j].y) <= 
                        (wo[i].r + wo[j].r) * (wo[i].r + wo[j].r)) {
                        g[i][j] = g[j][i] = 1;
                    }
                }
            }
        }
        /*
        for (i = 0; i <= n + 1; ++i) {
            for (j = 0; j <= n + 1; ++j)
                printf("%d ", g[i][j]);
            printf("\n");
        }*/
        ans = 0;
        dfs(up);
        if (ans == 1) {
            printf("Bill will be bitten.\n");
        } else {
            double ansl = 1000.0;
            double ansr = 1000.0;
            for (i = 0; i < n; ++i) {
                if (wo[i].left!= -1 && g[i][up] == 1) {
                    ansl = wo[i].left;
                }
                if (wo[i].right!= -1 && g[i][up] == 1) {
                    ansr = wo[i].right;
                }
            }
            printf("Bill enters at (0.00, %.2lf) and leaves at (1000.00, %.2lf).\n", ansl, ansr);
        }
    }
    return 0;
}


你可能感兴趣的:(UP)