UVAlive 4035 Undetectable Tour

Mickey is assigned a task to help the puppies to escape by travelling from the south-west corner of a grid to the north-east corner undetected by the set of motion detectors deployed by Cruella. There are k motion detectors (1k300) which are placed on the grid points and can detect any motion within a given distance, d , from the detector. Here we adopt L1 metrics for distance measurements, i.e., the distance between two points (x1y1) and (x2y2) is x1 - x2| + | y1 - y2| . For example, consider the 9×9 grid in the figure below, if the detecting distance of the two detectors, marked with a solid circle, is 3, there exists a tour from (0, 0) to (8, 8) (for example the diagonal is an undetectable tour); however, if the distance is four, there would be no such tour.

Cruella decides to make it more difficult to escape by setting the detecting distance of the detectors randomly. For each grid, Cruel would flip coins to decide the detecting distance for all the detectors in that grid. Given the probability distribution of the detecting distance d and a series of grids, your task is to write a program to decide for each input grid the probability that it contains an undetectable tour.

Each grid is N×N where 3N10000 , and each grid point in the grid is denoted by a pair of integers, (xy) , where 0x , yN - 1 . The probability distribution is specified by a sequence of ordered pair (d1p1),(d2p2),...,(dmpm) where 1m100, 1di2(N - 1) , and each pi has at most three digits after the decimal point. To make it a probability distribution we also have the property that pi = 1 .

Input 

The first line of the input file contains an integer indicating the number of test cases to follow, there will be at most 5 test cases. For each test case, the first line contains two integers, N and m separated by a space. Followed by m lines to specify the probability distribution, each line consists dipi . Followed by k lines of the positions of detectors in the form x ,y which is the coordination of the detector. The case ends with a line containing `-1'.

Output 

For each test case, output the probability that the grid contains a undetectable tour.

Sample Input 

2 
3 2 
1 0.5 
2 0.5 
2 0 
-1 
6 3 
1 0.5 
4 0.25 
3 0.25 
5 1 
1 5 
-1

Samle Output 

0.5 

0.75

如果不能从左下角到右上角,则必定是有一些相连的探测器,从左上边界一直连接到右下边界。那对于每个固定的探测器半径,可以用并查集快速判断是否存在从左上到右下的相连探测器。

#include<cstdio>
#include<map>
#include<queue>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<list>
#include<set>
#include<cmath>
using namespace std;
const int maxn = 1e4 + 5;
const int INF = 1e9;
const double eps = 1e-6;
typedef unsigned long long ULL;
typedef long long LL;
typedef pair<int, int> P;
#define fi first
#define se second

typedef pair<int, double> P1;
P1 rad[105];
P pos[305];
int fa[305];
int cnt;
int n;

int Find(int x){return x==fa[x]?x:fa[x]=Find(fa[x]);}
int Abs(int x){return x<0?-x:x;}

int dis(int x1, int y1, int x2, int y2){
    return Abs(x1-x2)+Abs(y1-y2);
}

void connect(int x, int y){
    int X = Find(x);
    int Y = Find(y);
    if(X != Y)
        fa[X] = Y;
}

bool test(int limit){
    for(int i = 0;i < cnt+10;i++)
        fa[i] = i;
    for(int i = 0;i < cnt;i++){
        int x = pos[i].fi;
        int y = pos[i].se;
        if(x+limit>=n-1 || y-limit <= 0){
            connect(i, cnt+1);
        }
        if(x-limit <= 0 || y+limit >= n-1){
            connect(i, cnt+2);
        }
    }

    for(int i = 0;i < cnt;i++){
        int x1 = pos[i].fi;
        int y1 = pos[i].se;
        for(int j = i+1;j < cnt;j++){
            int x2 = pos[j].fi;
            int y2 = pos[j].se;
            if(dis(x1, y1, x2, y2) <= 2*limit){
                connect(i, j);
            }
        }
    }

    if(Find(cnt+1) == Find(cnt+2))
        return false;
    return true;
}

int main(){
    int t, m;
    scanf("%d", &t);
    while(t--){
        scanf("%d%d", &n, &m);
        for(int i = 0;i < m;i++){
            scanf("%d%lf", &rad[i].fi, &rad[i].se);
        }
        sort(rad, rad+m);
        cnt = 0;
        while(1){
            int x, y;
            scanf("%d", &x);
            if(x == -1)
                break;
            scanf("%d", &y);
            pos[cnt++] = P(y, x);
        }
        double ans = 0;
        for(int i = 0;i < m;i++){
            if(test(rad[i].fi))
                ans += rad[i].se;
            else
                break;
        }
        cout << ans << endl;
    }
    return 0;
}


你可能感兴趣的:(UVAlive 4035 Undetectable Tour)