UVA 1039(UVALive 3270) Simplified GSM Network (计算几何二分+最短路)

题面

Mobile phones have changed our lifestyle dramatically in the last decade. Mobile phones have a variety of protocols to connect with one another. One of the most popular networks for mobile phones is the GSM (Global System for Mobile Communication) network.


Figure: Cities here are represented by squares and BTS towers by trapezoids. Solid lines are roads. The dotted lines show 9 different cells. The minimum number of switches required to go from city 1 to city 6 is (2+1+0)=3. Note that city 7 is isolated and cannot be reached.
In a typical GSM network, a mobile phone connects with the nearest BTS (Base Transceiver Station). A BSC (Base Station Center) controls several BTSs. Several BSCs are controlled by one MSC (Mobile Services Switching Center), and this MSC maintains a connection with several other MSCs, a PSTN (Public Switched Telecom Network) and an ISDN (Integrated Services Digital Network).
This problem uses a simplified model of the conventional GSM network. Our simplified network is composed of up to fifty BTS towers. When in use, a mobile phone always connects to its nearest BTS tower. The area covered by a single BTS tower is called a cell. When an active mobile phone is in motion, as it crosses cell boundaries it must seamlessly switch from one BTS to another. Given the description of a map consisting of cities, roads and BTS towers, you must determine the minimum number of BTS switches required to go from one city to another. Each tower and each city location is to be considered as a single point in a two-dimensional Cartesian coordinate system. If there is a road between two cities, assume that the road is a straight line segment connecting these two cities. For example, in the figure, traveling on the road from city 1 to city 2 will cross two cell boundaries and thus requires two switches. Traveling from city 2 to city 5 crosses one cell boundary and traveling from city 5 to city 6 requires no switch. Traveling this route from city 1 to city 6 requires three total switches. Note than any other path from city 1 to city 6 requires more than three switches. If there is more than one possible way to get from one city to another, your program must find the optimal route.
Input The input file contains several test cases. The first line of each test case contains four integers: B(1 ≤ B ≤ 50), the number of BTS towers; C(1 ≤ C ≤ 50), the number of cities; R(0 ≤ R ≤ 250), the number of roads; and Q(1 ≤ Q ≤ 10), the number of queries. Each of the next B lines contains two floating-point numbers x and y, the Cartesian coordinates of a BTS tower. Each of the next C lines contains two floating-point numbers xi, yi that indicate the Cartesian coordinates of the ith city (1 ≤ i ≤ C). Each of the next R lines contains two integers m and n (1 ≤ m,n ≤ C), which indicate that there is a road between the m-th and the n-th city. Each of the next Q lines contains two integers s and d (1 ≤ s,d ≤ C), the source and destination cities. No coordinate will have an absolute value greater than 1000. No two towers will be at the same location. No two cities will be at the same location, and no city will lie on a cell boundary. No road will be coincident with a cell boundary, nor contain a point lying on the boundary of three or more cells.
The input will end with a line containing four zeros.
Output
For each input set, you should produce Q + 1 lines of output, as shown below. The first line should contain the number of the test case. Q lines should follow, one for each query, each containing an integer indicating the minimum number of switches required to go from city s to city d. If it is not possible to go from city s to city d, print the line ‘Impossible’ instead.
Sample Input
9 7 6 2 5 5 15 5 25 5 5 15 15 15 25 15 5 25 15 25 25 25 8 2 22 3 8 12 18 18 22 12 28 16 28 8 1 2 1 3 2 5 3 4 4 5 5 6 1 6 1 7 0 0 0 0
Sample Output
Case 1: 3 Impossible

题目链接

UVA_1039

参考链接

百度百科 voronoi图

算法合集之《计算几何中的二分思想》

二分+最短路 uvalive 3270 Simplified GSM Network(推荐) Author:blues

题意简述

每个基站覆盖一片区域,求两个城市之间最少需要多少次基站的交换。

分析

先求每条路需要转换的次数,即权值。

一条线段的交换次数==左线段的交换次数+右线段的交换次数,用分治法求解每条线段的转换次数。

再用Dijkstra求Start和End之间的最短路。

程序简述

double cal_dis(Point a,Point b)/**计算两点之间的距离**/

int cal_belong(Point now)/**计算now点的所属基站**/

int cal_w(Point a,Point b)/**计算线段a-b的交换次数**/

void add_edge(int u,int v)/**u,v之间加双向边**/

程序

#include<stdio.h>
#include<queue>
#include<math.h>
#include<vector>
#include<string.h>
using namespace std;
#define INF 0x3f3f3f3f
int B,C,R,Q;
bool visit[55];
int dis[55];
struct Point
{
    double x,y;
    Point(double X,double Y):x(X),y(Y){}
    Point(){}
}tower[55],city[55];

struct Edge
{
    int to,w;
    Edge(int To,int W):to(To),w(W){}
    Edge(){}
};
vector<Edge>e[255];

struct node
{
    int num,val;
    node(int n,int v):num(n),val(v){}
    friend bool operator < (node a,node b)
    {
        return a.val>b.val;
    }
};

void init()
{
    for(int i=0;i<=C;i++)
        e[i].clear();
}

double cal_dis(Point a,Point b)
{
    double d_x=a.x-b.x;
    double d_y=a.y-b.y;
    return sqrt(d_x*d_x+d_y*d_y);
}

int cal_belong(Point now)
{
    int Tower;
    double length=(double)INF;
    int which;
    for(int j=1;j<=B;j++)
    {
        double temp_l=cal_dis(now,tower[j]);
        if(temp_l<length)
        {
            length=temp_l,Tower=j;
        }
    }
    return Tower;
}

int cal_w(Point a,Point b)
{
    if(cal_belong(a)==cal_belong(b))
        return 0;
    if(cal_dis(a,b)<1e-6)
        return 1;
    Point middle((a.x+b.x)/2.0,(a.y+b.y)/2.0);
    return cal_w(a,middle)+cal_w(middle,b);
}

void add_edge(int u,int v)
{
    int w=cal_w(city[u],city[v]);
    e[u].push_back(Edge(v,w));
    e[v].push_back(Edge(u,w));
}

int dijkstra(int Start,int End)
{
    memset(visit,0,sizeof(visit));
    memset(dis,INF,sizeof(dis));
    dis[Start]=0;
    priority_queue<node>q;
    q.push(node(Start,0));
    while(!q.empty())
    {
        node p=q.top();
        q.pop();
        int p_num=p.num;
        if(visit[p_num])
            continue;
        visit[p_num]=true;
        if(p_num==End)
            return dis[End];
        for(int i=0;i<e[p_num].size();i++)
        {
            Edge temp_e=e[p_num][i];
            if(dis[temp_e.to]>dis[p_num]+temp_e.w&&!visit[temp_e.to])
            {
                dis[temp_e.to]=dis[p_num]+temp_e.w;
                q.push(node(temp_e.to,dis[temp_e.to]));
            }
        }
    }
    return INF;
}

int main()
{
    int e=1;
    while(scanf("%d%d%d%d",&B,&C,&R,&Q)&&(B||C||R||Q))
    {
        init();
        for(int i=1;i<=B;i++)
            scanf("%lf%lf",&tower[i].x,&tower[i].y);
        for(int i=1;i<=C;i++)
            scanf("%lf%lf",&city[i].x,&city[i].y);
        for(int j=1;j<=R;j++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            add_edge(u,v);
        }
        printf("Case %d:\n",e++);
        for(int j=0;j<Q;j++)
        {
            int Start,End;
            scanf("%d%d",&Start,&End);
            int answer=dijkstra(Start,End);
            if(answer==INF)
                printf("Impossible\n");
            else
                printf("%d\n",answer);
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值