201403-4 无线网络 100分 31ms

点击前往试题目录:https://blog.csdn.net/best335/article/details/99550556
在这里插入图片描述
考点:BFS

#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
int n,m,k,r,E[200][2],INF=0x7fffffff,LOG[200],N,dis[200][200];
int BFS(int v,int _k,int _d){
	if(_k>k||_d>=LOG[v]) return INF;//超过满足题意的K或者已经遍历过
	LOG[v]=_d;//记录v的最小遍历深度
	int __d=_d+1,ans=INF,__k=_k+1;
	//开始遍历所能到达的点 判断是否能够到达目的点
	for(int i=1;i<n;++i){
		if(dis[v][i]==-1)//计算 v i的距离 取上溢
			dis[v][i]=dis[i][v]=ceil(sqrt(pow(abs(E[v][0]-E[i][0]),2.0)+pow(abs(E[v][1]-E[i][1]),2.0)));
		if(dis[v][i]<=r&&LOG[i]>__d){
			if(dis[i][1]==-1)
				dis[1][i]=dis[i][1]=ceil(sqrt(pow(abs(E[1][0]-E[i][0]),2.0)+pow(abs(E[1][1]-E[i][1]),2.0)));
			if(dis[i][1]<=r)
				return __d;
		}
	}
	if(__k<=k)//遍历可增设点
		for(int i=n;i<N;++i){
			if(dis[v][i]==-1)
				dis[v][i]=dis[i][v]=ceil(sqrt(pow(abs(E[v][0]-E[i][0]),2.0)+pow(abs(E[v][1]-E[i][1]),2.0)));
			if(dis[v][i]<=r&&LOG[i]>__d){
				if(dis[i][1]==-1)
					dis[1][i]=dis[i][1]=ceil(sqrt(pow(abs(E[1][0]-E[i][0]),2.0)+pow(abs(E[1][1]-E[i][1]),2.0)));
				if(dis[i][1]<=r)
					return __d;
			}
		}
	//对所有的可到达点做BFS
	for(int i=2,ni=__k>k?n:N;i<ni;++i){
		if(dis[v][i]<=r)
			ans=min(ans,BFS(i,i<n?_k:__k,__d));
	}
	return ans;
}
int main(){
	cin>>n>>m>>k>>r;
	memset(LOG,0x7f,sizeof(LOG));//初始化深度
	memset(dis,-1,sizeof(dis));//初始化任意两点距离
	for(int i=0,ni=N=n+m;i<ni;++i) cin>>E[i][0]>>E[i][1];//N=n+m E输入
	cout<<BFS(0,0,0)<<endl;
	return 0;
}

之前做的

#include <iostream>
#include <vector>
#include <math.h>
#include <string.h>
#include <algorithm>
using namespace std;

int n,m,k,N,ans;         //题意n,m,k     N=m+n    ans结果 
vector<vector<int> >vvi; //两点连接状态 
unsigned long long r;    //半径的平方 
struct Point { int x,y; Point(int x=0,int y=0):x(x),y(y){} };
vector<Point>vP;         //放置输入的路由器位置 
vector<bool>global;      //贪心连接  减少重复计算 
vector<int>vQ,vQT,vK,vKT;//vQ同一深度放置的路由器 vK同一深度放置的路由器已增设的路由器个数  vQT下一深度路由器位置  vKT下一深度已增设 

inline bool CanCall(const int& P1,const int& P2)
{
	if (P1>P2) return CanCall(P2,P1);
	if (vvi[P1][P2]!=-1) return vvi[P1][P2]==1;
	unsigned long long a=abs(vP[P1].x-vP[P2].x),b=abs(vP[P1].y-vP[P2].y);
	return (vvi[P1][P2]=(a*a+b*b<=r)?1:0)==1;
}

int main()
{
	cin>>n>>m>>k>>r,r*=r,N=n+m,ans=0,vvi=vector<vector<int> >(N,vector<int>(N,-1));//处理输入 
	for (int i=0,x,y;i<n;++i) cin>>x>>y,vP.push_back(Point(x,y));
	for (int i=0,x,y;i<m;++i) cin>>x>>y,vP.push_back(Point(x,y));//结束输入 
	if (CanCall(0, 1)) {cout<<0<<endl,vvi.clear(),vP.clear();return 0;}//如果两点直接可以连接 结束 
	global=vector<bool>(N,false);//初始化路由器放置状态 
	for (int i=2;i<N;++i) if (CanCall(0,i)) vQ.push_back(i),vK.push_back(0),global[i]=true;//如果路由器能够连接到第一个路由器 则加入到vQ中 并把K值初始化 
	while (vQ.size()>0)
	{
		++ans;//更新深度 
		for (int i=0,ni=vQ.size();i<ni;++i)//对该ans深度的所有的点进行遍历 
		{
			if (CanCall(1,vQ[i])&&vK[i]<=k) {vQT.clear(),vQ.clear(),vK.clear(),vKT.clear();break;}//该点可以直接连接第二个路由器 结束 一定是最小值 
			for (int j=2;j<N;++j) if(!global[j]&&CanCall(vQ[i],j)) vQT.push_back(j),vKT.push_back(vK[i]+(j<n?0:1)),global[j]=true;//遍历所有的点若没有放置过,并且能够连接 vQ[i] 置放置状态 加入下一深度 加入K 
		}
		vQ.clear(),vQ=vQT,vQT.clear(),vK.clear(),vK=vKT,vKT.clear();//更新下一深度路由信息 
	}
	cout<<ans<<endl,vvi.clear(),vP.clear(),global.clear();//输出结果 清除占用内存 
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值