[睡梦前的灵感]仓库路线设计
【描述】
ACK 是一家以生产计算机及其外设产品为主的高科技企业。不仅ACK 的产品在国内领先,而且它的仓库设计也独具特色。由于生产的产品多种多样,ACK的仓库是由若干个大小不等、形状各异的子仓库组成,每个仓库有一个入口(也是出口),坐标为(Xi,Yi)。由于有些产品是互相关联的,所以某些仓库的入口之间通过地下通道相联。(0,0)是地下通道的入口处。每次装卸货物时,仓库的运输车都要从(0,0)处进入地下通道,在通道中行驶一段距离后进入到某一子仓库中装卸货物。但是最近运输车出现了一点小毛病,那就是运输车只能右转弯,而不能左转弯。这对运输车在仓库中运输货物并没有什么影响,但是由于地下通道的宽度有限,运输车转弯的角度不能超过180 (180度也不行)。在这种情况下,某些仓库仍然是可到达的,但是有些仓库却是根本不能到达的。

例如在如上图的例子中,如果运输车的行驶路线为O—B—D—E—F—B—A(这条路线保证了运输车不进行左转弯),则可依次到达子仓库B、D、E、F、A,但是无论运输车如何选择其他的路线,子仓库C 都是不能到达的。
作为ACK 的高级工程师,请你编程找出从O点可以到达的所有子仓库。
注意:为保持仓库的清洁,地下通道采用“管道”的形式(除入口和出口以外都是封闭的),所以即使仓库i 和仓库j 相连,仓库k 的坐标为(Xk,Yk)在(Xi,Yi)和(Xj,Yj)的连线上,当运输车在从仓库i 到仓库j 的路线上时仍不能到达仓库k。
【输入格式】
输入数据文件名为line.in 。文件的第一行为一个整数N(n<=200),表示共有N个子仓库。从第二行开始到第(N+1)行每行有两个数Xi,Yi,(-50<=Xi,Yi<=50)表示第i 个仓库的坐标。然后是一个整数M(M<=100) ,表示共有M 条路线。接下来的M 行每行有两个整数P、Q,表示子仓库P 和子仓库Q 有通道相连,在这里通道是双向的,即如果P 可以和Q相连,那么Q 也一定和P 相连。其中仓库的入口(0,0)用0 表示。
【输出格式】
输出文件为line.out。将可能到达的子仓库序号按升序输出到文件中。输入文件中给出的数据保证至少有一个可达子仓库。
【样例输入】
6
0 4
1 2
2 4
2 3
3 2
2 1
8
0 2
1 2
1 4
2 4
3 4
4 5
5 6
2 6
【样例输出】
1 2 4 5 6
【分析】
题目就是一个限定了条件的宽搜。

对于当前处理的点2,设上一个点是1,判断的点是3。可以进行扩展的条件是a×b>0或者a和b是同向共线向量。然后由于一个点可能扩展到多次,但是一个边(有向)只能扩展到一次,利用这个来限制宽搜。原来用的限制方法是一个点搜到一次……晚上躺床上突然就想出来了的说。好神奇。
#include <stdio.h>
#define maxn 210
bool v[maxn][maxn];
struct ss
{
int x,y;
} a[maxn];
int que[maxn*maxn];
struct sss
{
int x1,y1;
} b[maxn];
int n,m,p,q,h,t;
int bl[maxn][maxn];
int tx,ty,nx,ny,tnode,nnode;
bool can[maxn];
bool ok(int x1,int y1,int x2,int y2)
{
return ((x1*y2-x2*y1>0)||((x1*y2==x2*y1)&&(x1*x2<=0)));
}
int main()
{
freopen("line.in","r",stdin);
freopen("line.out","w",stdout);
scanf("%d",&n);
for (int i=1;i<=n;++i) scanf("%d%d",&a[i].x,&a[i].y);
scanf("%d",&m);
for (int i=1;i<=m;++i)
{
scanf("%d%d",&p,&q);
bl[q][++bl[q][0]]=p;
bl[p][++bl[p][0]]=q;
}
while (h<=t)
{
nnode=que[h];
nx=a[nnode].x;
ny=a[nnode].y;
if (!h)
for (int i=1;i<=bl[0][0];++i)
{
tnode=bl[0][i];
v[0][tnode]=1;
can[tnode]=1;
que[++t]=tnode;
}
else
for (int i=1;i<=bl[nnode][0];++i)
{
tnode=bl[nnode][i];
tx=a[tnode].x;
ty=a[tnode].y;
if (ok(b[h].x1-nx,b[h].y1-ny,tx-nx,ty-ny))
if (!v[nnode][tnode])
{
can[tnode]=1;
que[++t]=tnode;
b[t].x1=nx;
b[t].y1=ny;
v[nnode][tnode]=1;
}
}
++h;
}
for (int i=1;i<=n;++i)
if (can[i]) printf("%d ",i);
return 0;
}
浙公网安备 33010602011771号