CCF认证201403-4无线网络

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/richenyunqi/article/details/87906639

欢迎访问我的CCF认证考试题解目录哦 https://blog.csdn.net/richenyunqi/article/details/83385502

题目描述

CCF认证201403-4无线网络题目描述

算法设计

将所有的路由器存储到一个vector变量中。将每一个路由器看作是一个结点,结点编号为路由器在vector中的下标,如果两个无线路由器只要距离不超过r,就认为这两个路由器之间存在一条边,则整个问题就变成了求解0号结点到1号结点之间的最短路径。
由于最短路径的度量是最少经过的中转路由器的个数,所以可以把整个图看成是无权图,可以利用BFS算法求解,只不过在算法中需要考虑一下增设的路由器不能超过k这个条件即可。具体实现可见代码。

注意点

由于涉及到平方运算,坐标以及r最好都用long long类型来存储。

C++代码

#include<bits/stdc++.h>
using namespace std;
struct Router{//路由器
    long long x,y;//坐标
    int cost=0,addNum=0;//经过的路由器个数、增设的路由器个数
    bool add;//是否是增设的路由器
    Router(long long xx,long long yy,bool a=false):x(xx),y(yy),add(a) {}
};
int n,m,k,r;
vector<Router>routers;//存储路由器
inline bool canReach(int i,int j){//计算两个路由器之间的距离是否超过r
    return (routers[i].x-routers[j].x)*(routers[i].x-routers[j].x)+
            (routers[i].y-routers[j].y)*(routers[i].y-routers[j].y)<=(long long)r*r;
}
int main(){
    scanf("%d%d%d%d",&n,&m,&k,&r);
    long long a,b;
    while(n--){
        scanf("%lld%lld",&a,&b);
        routers.push_back(Router(a,b));
    }
    while(m--){
        scanf("%lld%lld",&a,&b);
        routers.push_back(Router(a,b,true));
    }
    vector<bool>inQueue(routers.size(),false);//标志一个路由器是否已经入过队
    queue<int>q;
    q.push(0);
    inQueue[0]=true;
    while(!q.empty()){
        int t=q.front();
        q.pop();
        if(t==1)//到达1号结点,跳出循环
            break;
        for(int i=0;i<routers.size();++i)//遍历所有路由器
            if(!inQueue[i]&&canReach(t,i)){//没有入过队且从t号路由器可以到达该路由器
                if(routers[i].add&&routers[t].addNum+1>k)//如果该路由器是增设路由器且增设的路由器超过了k
                    continue;//不进行任何操作
                routers[i].cost=routers[t].cost+1;//经过的路由器个数+1
                routers[i].addNum=routers[t].addNum+(routers[i].add?1:0);//更新经过的增设路由器个数
                inQueue[i]=true;
                q.push(i);//入队
            }
    }
    printf("%d",routers[1].cost-1);//输出
    return 0;
}

猜你喜欢

转载自blog.csdn.net/richenyunqi/article/details/87906639