题目链接:https://vjudge.net/contest/202436#problem/B

题意:已知B(1≤B≤50)个信号站和C(1≤C≤50)座城市的坐标,坐标的绝对值不大于1000,每个城市使用最近的信号站。给定R(1≤R≤250)条连接城市线路的描述和Q(1≤Q≤10)个查询,求相应两城市间通信时最少需要转换信号站的次数。

解法:


#include <bits/stdc++.h>
using namespace std;
struct node{
    int x,y;
};
const int MaxB = 50;
const int MaxC = 50;
const int MaxS = 50*50;
int B, C, R, Q;
node BTS[MaxB], city[MaxC];
int S[MaxC][MaxC];
double dis(double x1, double y1, double x2, double y2){
    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
int area(double x, double y){
    int i,k;
    double minn,tmp;
    minn = dis(x,y,BTS[0].x,BTS[0].y);
    k=0;
    for(int i=1;i<B;i++){
        tmp = dis(x,y,BTS[i].x,BTS[i].y);
        if(tmp<minn){
            minn = tmp;
            k = i;
        }
    }
    return k;
}
int get_switch(double x1, double y1, double x2, double y2){
    if(area(x1,y1)==area(x2,y2)) return 0;
    if(dis(x1,y1,x2,y2)<1e-6) return 1;
    return get_switch(x1,y1,(x1+x2)/2,(y1+y2)/2)+get_switch((x1+x2)/2,(y1+y2)/2, x2,y2);
}

int main(){
    int ks = 0;
    while(~scanf("%d%d%d%d",&B,&C,&R,&Q)){
        if(B==0&&C==0&&R==0&&Q==0) break;
        for(int i=0; i<B; i++) scanf("%d%d", &BTS[i].x,&BTS[i].y);
        for(int i=0; i<C; i++) scanf("%d%d", &city[i].x,&city[i].y);
        memset(S, 0, sizeof(S));
        for(int i=0; i<R; i++){
            int x, y;
            scanf("%d %d", &x,&y);
            x--;
            y--;
            S[x][y]=S[y][x]=1;
        }
        for(int i=0; i<C; i++){
            for(int j=i+1; j<C; j++){
                if(S[i][j]==0) S[i][j]=MaxS;
                else S[i][j] = get_switch(city[i].x,city[i].y,city[j].x,city[j].y);
                S[j][i]=S[i][j];
            }
        }
        for(int i=0;i<C;i++) S[i][i]=0;
        for(int k=0; k<C; k++)
            for(int i=0; i<C; i++)
                for(int j=0; j<C; j++)
                    if(S[i][j]>S[i][k]+S[k][j])
                        S[i][j] = S[i][k]+S[k][j];
        printf("Case %d:\n", ++ks);
        for(int i=0; i<Q; i++){
            int x, y;
            scanf("%d %d", &x,&y);
            x--;
            y--;
            if(S[x][y]>=MaxS) puts("Impossible");
            else printf("%d\n", S[x][y]);
        }
    }
}