这个题是求最短路,只不过需要处理一下,将所有中间没有其他加油站的点进行连边,权值为1,然后求1->2的最短路即可
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<algorithm>
#include<set>
using namespace std;
const int inf=1<<29;
const int maxn=1100;
const int maxm=maxn*maxn;
struct Node
{
long long x;
long long y;
int pos;
bool operator < (const Node &a)const
{
if(x==a.x)
return y<a.y;
return x<a.x;
}
}a[maxn];
long long l;
int n,e,head[maxn],nxt[maxm],pnt[maxm],cost[maxm],dist[maxn];
bool vis[maxn];
queue<int> q;
set<pair<int,int> > pi;
long long Dis(int i,int j)
{
return (a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y);
}
void AddEdge(int u,int v,int c)
{
pnt[e]=v;nxt[e]=head[u];cost[e]=c;head[u]=e++;
pnt[e]=u;nxt[e]=head[v];cost[e]=c;head[v]=e++;
}
void Spfa(int st,int des)
{
for(int i=0;i<n+2;i++)
dist[i]=inf;
dist[st]=0;
q.push(st);
while(!q.empty())
{
int u=q.front();
vis[u]=0;
q.pop();
for(int i=head[u];i!=-1;i=nxt[i])
if(dist[pnt[i]]>dist[u]+cost[i])
{
dist[pnt[i]]=dist[u]+cost[i];
if(!vis[pnt[i]])
{
q.push(pnt[i]);
vis[pnt[i]]=1;
}
}
}
if(dist[des]==inf)
printf("impossible\n");
else
printf("%d\n",dist[des]-1);
}
bool check(int si,int sj)
{
int sy=a[sj].y-a[si].y;
int sx=a[sj].x-a[si].x;
int py=sy/__gcd(sx,sy);
int px=sx/__gcd(sx,sy);
if(pi.find(make_pair(px,py))!=pi.end())
return false;
pi.insert(make_pair(px,py));
return true;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
e=0;
memset(head,-1,sizeof(head));
scanf("%d%I64d",&n,&l);
for(int i=0;i<n+2;i++)
{
scanf("%I64d%I64d",&a[i].x,&a[i].y);
a[i].pos=i;
}
sort(a,a+n+2);
long long sl=l*l;
for(int i=0;i<n+2;i++)
{
pi.clear();
for(int j=i+1;j<n+2;j++)
{
if(Dis(i,j)<=sl&&check(i,j))
AddEdge(a[i].pos,a[j].pos,1);
}
}
Spfa(0,1);
}
return 0;
}