hdu4885

来源:互联网 发布:又见白娘娘淘宝可信吗 编辑:程序博客网 时间:2024/06/05 02:17

题意:给你n个加油站的坐标,和起点终点坐标, 然后你开车用起点到终点, 你的车最多只能开L米,每经过一个加油站必定要加油,问你要加油几次。
先建图,跑个bfs即可,注意由于每经过一个加油站都要加油,所以路线不能重叠,所以要判一下斜率相等。

#include<bits/stdc++.h>using namespace std;typedef long long ll;ll ex,ey,sx,sy,l;int n,s,tt,dis[1005];vector<int> ma[1005];struct node{    ll x,y;} di[1005],tmp;set<pair<ll,ll> > q;ll get(int i,int j){    return (di[i].x-di[j].x)*(di[i].x-di[j].x)+(di[i].y-di[j].y)*(di[i].y-di[j].y);}bool cmp(node a,node b){    return a.x<b.x;}void bfs(){    queue<int> qq;    qq.push(s);    memset(dis,-1,sizeof(dis));    dis[s]=0;    while(!qq.empty())    {        int cur=qq.front();        qq.pop();        for(int i=0; i<ma[cur].size(); i++)        {            int v=ma[cur][i];            if(dis[v]==-1)            {                dis[v]=dis[cur]+1;                if(tt==v)                {                    printf("%d\n",dis[v]-1);                    return;                }                qq.push(v);            }        }    }    puts("impossible");}int main(){    int t;    scanf("%d",&t);    while(t--)    {        scanf("%d%I64d",&n,&l);        n+=2,q.clear(),l*=l;        for(int i=0;i<n;i++)            ma[i].clear();        scanf("%I64d%I64d%I64d%I64d",&sx,&sy,&ex,&ey);        di[0].x=sx,di[0].y=sy,di[1].x=ex,di[1].y=ey;        for(int i=2; i<n; i++)            scanf("%I64d%I64d",&di[i].x,&di[i].y);        sort(di,di+n,cmp);        for(int i=0; i<n; i++,q.clear())        {            if(di[i].x==sx&&di[i].y==sy)s=i;            if(di[i].x==ex&&di[i].y==ey)tt=i;            for(int j=i+1; j<n; j++)            {                ll len=get(i,j);                if(len>l) continue;                ll g=__gcd(di[i].x-di[j].x,di[i].y-di[j].y);                if(g<0) g=-g;                if(q.find({(di[i].x-di[j].x)/g,(di[i].y-di[j].y)/g})!=q.end())continue;                q.insert({(di[i].x-di[j].x)/g,(di[i].y-di[j].y)/g});                ma[i].push_back(j);                ma[j].push_back(i);            }        }        bfs();    }}
0 0