您的位置:首页 > 其它

hdu 4885

2015-09-08 21:44 302 查看
/* 题意:给你一个起点,一个终点和一些加油站,你只能走直线,只能到达这三种点,经过加油站必须加油,
一次加油可以走L的距离,问最少经过加油站几次可以从起点到达终点*/

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <map>
#include <algorithm>
#define INF 0x3f3f3f3f
#define maxn 1005
#define MAXN 2000005
#define eps 1e-10
typedef long long ll;
using namespace std;

ll n,m,ans,cnt,sx;
bool vis[maxn];
ll dist[maxn],head[maxn],id[maxn][maxn];
struct node
{
ll x,y,id;
bool operator <(const node n1)const
{
if(x*n1.x>=0) return  y*n1.x<n1.y*x;
return y*n1.x>n1.y*x;
}
}q[maxn],cur;

struct Node
{
ll v,w,next;
}edge[MAXN];

void addedge(ll u,ll v,ll w)
{
cnt++;
edge[cnt].v=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt;
}
ll cal(ll i,ll j)
{
ll xx=q[i].x-q[j].x,yy=q[i].y-q[j].y;
return xx*xx+yy*yy;
}

void SPFA()
{
ll i,j,nx,v;
memset(vis,0,sizeof(vis));
memset(dist,0x3f,sizeof(dist));
sx=1;
queue<ll>q;
dist[sx]=0;
vis[sx]=1;
q.push(sx);
while(!q.empty())
{
nx=q.front();
vis[nx]=0;
q.pop();
for(i=head[nx];i;i=edge[i].next)
{
v=edge[i].v;
if(dist[v]>dist[nx]+edge[i].w)
{
dist[v]=dist[nx]+edge[i].w;
if(!vis[v])
{
vis[v]=1;
q.push(v);
}
}
}
}
}

void solve()
{
ll i,j,t;
for(i=1;i<=n;i++)
{
map<node,ll>mp;
ll tot=0;
for(j=1;j<=n;j++)
{
if(q[j].y<q[i].y||q[j].y==q[i].y&&q[j].x<=q[i].x||cal(i,j)>m*m) continue ;
cur.y=q[j].y-q[i].y;
cur.x=q[j].x-q[i].x;
t=mp[cur];
if(t==0)
{
mp[cur]=++tot;
id[i][tot]=j;//tot是边的数目
}
else
{
if(q[id[i][t]].y>q[j].y||q[id[i][t]].y==q[j].y&&q[id[i][t]].x>q[j].x)
{
id[i][t]=j;
}
}
}
for(j=1;j<=tot;j++)
{
//printf("u:%I64d v:%I64d\n",i,id[i][j]);//去除不必要的建边
addedge(i,id[i][j],1);//去除了不能达到的边
addedge(id[i][j],i,1);
}
}
}

int main()
{
freopen("in.txt","r",stdin);
ll i,j,u,v,w,t;
scanf("%I64d",&t);
while(t--)
{
scanf("%I64d%I64d",&n,&m);
n+=2;
for(i=1;i<=n;i++)
{
scanf("%I64d%I64d",&q[i].x,&q[i].y);
q[i].id=i;
}
cnt=0;
memset(head,0,sizeof(head));
solve();
SPFA();//这里是标准的bfs
if(dist[2]>=INF) printf("impossible\n");
else printf("%I64d\n",dist[2]-1);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: