题意:
给你n个路由器,m个可以添加路由器的位置,但最多添加k个路由器,求从第 1 个路 由器到第 2 个路由器最少经过的中转路由器的个数
题解:
分层Dijkstra
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e2+5;
typedef long long ll;
int n,m,K,R,ans,Dis[maxn][105];
vector<int>vec[maxn];
ll stand;
struct point{
ll x,y;
}A[maxn];
struct node{
int id,cnt;
};
bool check(int id1,int id2){
ll tmp=(A[id1].x-A[id2].x)*(A[id1].x-A[id2].x)+(A[id1].y-A[id2].y)*(A[id1].y-A[id2].y);
if(tmp<=stand)return true;
return false;
}
void spfa(){
int i,j,lenV,next,tmp;
node now;
queue<node>qu;
for (i=1;i<=200;i++)for (j=0;j<=K;j++)Dis[i][j]=maxn;
ans=maxn;qu.push({1,0});Dis[1][0]=1;
while(!qu.empty()){
now=qu.front();qu.pop();
lenV=vec[now.id].size();
for (i=0;i<lenV;i++){
next=vec[now.id][i];
tmp=now.cnt;
if(next>n)tmp++;
if(tmp>K)continue;
if(Dis[next][tmp]>Dis[now.id][now.cnt]+1){
Dis[next][tmp]=Dis[now.id][now.cnt]+1;
qu.push({next,tmp});
}
}
}
for (i=0;i<=K;i++)ans=min(ans,Dis[2][i]-2);
printf("%d\n",ans);
}
int main(){
int i,j,upper;
while(scanf("%d%d%d%d",&n,&m,&K,&R)!=EOF){
for (i=0;i<=200;i++)vec[i].clear();
stand=1ll*R*R;upper=n+m;ans=maxn;
for (i=1;i<=upper;i++)scanf("%lld%lld",&A[i].x,&A[i].y);
for (i=1;i<=upper;i++){
for (j=i+1;j<=upper;j++){
if(check(i,j))vec[i].push_back(j),vec[j].push_back(i);
}
}
spfa();
}
return 0;
}