版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/clx55555/article/details/86482190
spfa算法介绍:https://blog.csdn.net/clx55555/article/details/52442410
两个路由器可以通讯则二者连一条无向边。
用d[i][j]表示从起点开始经过增设的j个路由器到达i的最短路径,vis[i][j]表示是否计算过从起点经过增设的j个路由器到达i,根据spfa算法的思想出栈的视为没计算过。
然后就和普通的最短路一样了。这里选用spfa求解。
最后d[1][0]~d[1][k]的最小值就是答案
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#define N 205
#define INF 0x3f3f3f3f
typedef long long LL;
using namespace std;
struct P{
int x,y;
}p[205];
int n,m,k,r;
int d[205][205];
bool vis[205][205],Map[205][205];
void spfa()
{
queue<P> q;
memset(vis,0,sizeof(vis));
memset(d,INF,sizeof(d));
d[0][0]=0;
vis[0][0]=1;
P s,tmp;
s.x=s.y=0;
q.push(s);
while(!q.empty())
{
s=q.front();
q.pop();
vis[s.x][s.y]=0;
for(int i=0;i<n+m;++i)
if(Map[s.x][i])
{
tmp.x=i;
tmp.y=s.y;
if(i>=n) ++tmp.y;
if(tmp.y<=k&&d[tmp.x][tmp.y]>d[s.x][s.y]+1)
{
d[tmp.x][tmp.y]=d[s.x][s.y]+1;
if(!vis[tmp.x][tmp.y])
{
vis[tmp.x][tmp.y]=1;
q.push(tmp);
}
}
}
}
int ans=INF;
for(int i=0;i<=k;i++) ans=min(ans,d[1][i]);
printf("%d\n",ans-1);
}
int main()
{
int i,j;
cin>>n>>m>>k>>r;
for(i=0;i<n+m;++i) scanf("%d%d",&p[i].x,&p[i].y);
memset(Map,0,sizeof(Map));
for(i=0;i<n+m;++i)
for(j=i+1;j<n+m;++j)
if(LL(p[i].x-p[j].x)*(p[i].x-p[j].x)+LL(p[i].y-p[j].y)*(p[i].y-p[j].y)<=LL(r)*r) Map[i][j]=Map[j][i]=1;
spfa();
return 0;
}