第二次CCF-4-无线网络(二维最短路-spfa)

来源:互联网 发布:python sys.exit 1 编辑:程序博客网 时间:2024/06/04 17:47

问题描述
试题编号:201403-4试题名称:无线网络时间限制:1.0s内存限制:256.0MB问题描述:
问题描述
  目前在一个很大的平面房间里有 n 个无线路由器,每个无线路由器都固定在某个点上。任何两个无线路由器只要距离不超过 r 就能互相建立网络连接。
  除此以外,另有 m 个可以摆放无线路由器的位置。你可以在这些位置中选择至多 k 个增设新的路由器。
  你的目标是使得第 1 个路由器和第 2 个路由器之间的网络连接经过尽量少的中转路由器。请问在最优方案下中转路由器的最少个数是多少?
输入格式
  第一行包含四个正整数 n,m,k,r。(2 ≤ n ≤ 100,1 ≤ k ≤ m ≤ 100, 1 ≤ r ≤ 108)。
  接下来 n 行,每行包含两个整数 xi 和 yi,表示一个已经放置好的无线 路由器在 (xi, yi) 点处。输入数据保证第 1 和第 2 个路由器在仅有这 n 个路由器的情况下已经可以互相连接(经过一系列的中转路由器)。
  接下来 m 行,每行包含两个整数 xi 和 yi,表示 (xi, yi) 点处可以增设 一个路由器。
  输入中所有的坐标的绝对值不超过 108,保证输入中的坐标各不相同。
输出格式
  输出只有一个数,即在指定的位置中增设 k 个路由器后,从第 1 个路 由器到第 2 个路由器最少经过的中转路由器的个数。
样例输入
5 3 1 3
0 0
5 5
0 3
0 5
3 5
3 3
4 4
3 0
样例输出
2

题解:做这题的时候想到了使用广搜,但是各种小问题无法解决,后来看了题解,发现巨巨的
二维最短路,真的很巧,这里仿照写了一发。。
dp[i][j]:终点为i用到j个外加路由器的最短路径。
vis[i][j]:起相应的标记作用。
代码如下:
#include<stdio.h>#include<string.h>#include<stdlib.h>#include<algorithm>#include<limits.h>#include<iostream>#include<queue>#include<string>#include<cstdio>#include<cstring>#include<stack>#include<vector>#include<math.h>#include<map>using namespace std;#define maxn 205#define INF 0x3f3f3f3f int dp[maxn][maxn],Map[maxn][maxn];bool vis[maxn][maxn];int n,m,k,r;struct node{int x,y;}a[maxn];struct road{int dis,num;};queue<road>q;void spfa(){int i,j;road s;dp[1][0]=0;s.dis=1;s.num=0;q.push(s);while(!q.empty()){road now=q.front();q.pop();vis[now.dis][now.num]=0;for(i=1;i<=n+m;i++){if(Map[now.dis][i]){road nexts;nexts.num=now.num;nexts.dis=i;if(i>n)nexts.num++;if(nexts.num<=k && dp[nexts.dis][nexts.num]>dp[now.dis][now.num]+1){dp[nexts.dis][nexts.num]=dp[now.dis][now.num]+1;if(!vis[nexts.dis][nexts.num]){vis[nexts.dis][nexts.num]=1;q.push(nexts);}}}}}int ans=INF;for(i=0;i<=k;i++)  ans=min(ans,dp[2][i]);printf("%d\n",ans-1);}int main(){memset(Map,0,sizeof(Map));memset(vis,0,sizeof(vis));memset(dp,INF,sizeof(dp));int i,j;scanf("%d%d%d%d",&n,&m,&k,&r);for(i=1;i<=n+m;i++)  scanf("%d%d",&a[i].x,&a[i].y);for(i=1;i<n+m;i++)  for(j=i+1;j<=n+m;j++)    if((long long)(a[i].x-a[j].x)*(a[i].x-a[j].x)+(long long)(a[i].y-a[j].y)*(a[i].y-a[j].y)<=(long long)(r)*r)         Map[i][j]=Map[j][i]=1;spfa();return 0;}

0 0