HOJ 12719 Eco-driving

二分最大转角,大于当前最大转角的就不松弛这条边了,跑SPFA看能不能到终点,由于只看判定性,所以一旦搜到终点就可以结束了。加了SLF优化,测试发现deque这样写效率还是挺高的……另外,松弛操作单独写一个update函数对于那种很麻烦的转移有奇效……

/*
 Author : Speedcell
 Update : 2013-10-08
Version : soppYcell 2.3
*/

#include <algorithm>
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>

#include <map>
#include <set>
#include <list>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <string>
#include <bitset>
#include <memory>
#include <complex>
#include <numeric>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <ctype.h>
#include <locale.h>

using namespace std;

#pragma pack(4)

#ifndef __CONSTANT__
#define __CONSTANT__

typedef long long LONG;

const double pi = acos(-1.0);
const int   inf = 0x7f7f7f7f;
const LONG  INF = 0x7f7f7f7f7f7f7f7fll;

const int go[8][2] = {{0,1},{0,-1},{1,0},{-1,0},{1,1},{1,-1},{-1,1},{-1,-1}};

#endif // __CONSTANT__

#ifndef __IO__
#define __IO__

inline bool RD(int    & a) {return scanf("%d",&a)!=EOF;}
inline bool RD(char   & a) {return scanf("%c",&a)!=EOF;}
inline bool RD(char   * a) {return scanf("%s", a)!=EOF;}
inline bool RD(double & a) {return scanf("%lf",&a)!=EOF;}
inline bool RD(LONG   & a) {return scanf("%I64d",&a)!=EOF;}

template<class T1> inline bool
    IN(T1 & a) {return RD(a);}
template<class T1,class T2> inline bool
    IN(T1 & a,T2 & b) {return RD(a)&&RD(b);}
template<class T1,class T2,class T3> inline bool
    IN(T1 & a,T2 & b,T3 & c) {return RD(a)&&RD(b)&&RD(c);}
template<class T1,class T2,class T3,class T4> inline bool
    IN(T1 & a,T2 & b,T3 & c,T4 & d) {return RD(a)&&RD(b)&&RD(c)&&RD(d);}
template<class T1,class T2,class T3,class T4,class T5> inline bool
    IN(T1 & a,T2 & b,T3 & c,T4 & d,T5 & e) {return RD(a)&&RD(b)&&RD(c)&&RD(d)&&RD(e);}
template<class T1,class T2,class T3,class T4,class T5,class T6> inline bool
    IN(T1 & a,T2 & b,T3 & c,T4 & d,T5 & e,T6 & f) {return RD(a)&&RD(b)&&RD(c)&&RD(d)&&RD(e)&&RD(f);}
template<class T1,class T2,class T3,class T4,class T5,class T6,class T7> inline bool
    IN(T1 & a,T2 & b,T3 & c,T4 & d,T5 & e,T6 & f,T7 & g) {return RD(a)&&RD(b)&&RD(c)&&RD(d)&&RD(e)&&RD(f)&&RD(g);}

inline void PT(int    a) {printf("%d",a);}
inline void PT(char   a) {printf("%c",a);}
inline void PT(char * a) {printf("%s",a);}
inline void PT(double a) {printf("%f",a);}
inline void PT(LONG   a) {printf("%I64d",a);}
inline void PT(const char a[]) {printf("%s",a);}

template<class T1> inline void
    OT(T1 a) {PT(a);}
template<class T1,class T2> inline void
    OT(T1 a,T2 b) {PT(a),PT(' '),PT(b);}
template<class T1,class T2,class T3> inline void
    OT(T1 a,T2 b,T3 c) {PT(a),PT(' '),PT(b),PT(' '),PT(c);}
template<class T1,class T2,class T3,class T4> inline void
    OT(T1 a,T2 b,T3 c,T4 d) {PT(a),PT(' '),PT(b),PT(' '),PT(c),PT(' '),PT(d);}
template<class T1,class T2,class T3,class T4,class T5> inline void
    OT(T1 a,T2 b,T3 c,T4 d,T5 e) {PT(a),PT(' '),PT(b),PT(' '),PT(c),PT(' '),PT(d),PT(' '),PT(e);}
template<class T1,class T2,class T3,class T4,class T5,class T6> inline void
    OT(T1 a,T2 b,T3 c,T4 d,T5 e,T6 f) {PT(a),PT(' '),PT(b),PT(' '),PT(c),PT(' '),PT(d),PT(' '),PT(e),PT(' '),PT(f);}
template<class T1,class T2,class T3,class T4,class T5,class T6,class T7> inline void
    OT(T1 a,T2 b,T3 c,T4 d,T5 e,T6 f,T7 g) {PT(a),PT(' '),PT(b),PT(' '),PT(c),PT(' '),PT(d),PT(' '),PT(e),PT(' '),PT(f),PT(' '),PT(g);}

template<class T1> inline void
    OL(T1 a) {PT(a),PT('\n');}
template<class T1,class T2> inline void
    OL(T1 a,T2 b) {PT(a),PT(' '),PT(b),PT('\n');}
template<class T1,class T2,class T3> inline void
    OL(T1 a,T2 b,T3 c) {PT(a),PT(' '),PT(b),PT(' '),PT(c),PT('\n');}
template<class T1,class T2,class T3,class T4> inline void
    OL(T1 a,T2 b,T3 c,T4 d) {PT(a),PT(' '),PT(b),PT(' '),PT(c),PT(' '),PT(d),PT('\n');}
template<class T1,class T2,class T3,class T4,class T5> inline void
    OL(T1 a,T2 b,T3 c,T4 d,T5 e) {PT(a),PT(' '),PT(b),PT(' '),PT(c),PT(' '),PT(d),PT(' '),PT(e),PT('\n');}
template<class T1,class T2,class T3,class T4,class T5,class T6> inline void
    OL(T1 a,T2 b,T3 c,T4 d,T5 e,T6 f) {PT(a),PT(' '),PT(b),PT(' '),PT(c),PT(' '),PT(d),PT(' '),PT(e),PT(' '),PT(f),PT('\n');}
template<class T1,class T2,class T3,class T4,class T5,class T6,class T7> inline void
    OL(T1 a,T2 b,T3 c,T4 d,T5 e,T6 f,T7 g) {PT(a),PT(' '),PT(b),PT(' '),PT(c),PT(' '),PT(d),PT(' '),PT(e),PT(' '),PT(f),PT(' '),PT(g),PT('\n');}

#endif // __IO__

#ifndef __MACRO__
#define __MACRO__

#define ML(times) int tcase; IN(tcase); FOR(times,1,tcase)

#define FOR(i,a,b) for(int i=int(a),_##i=int(b);i<=_##i;i++)
#define DWN(i,b,a) for(int i=int(b),_##i=int(a);_##i<=i;i--)
#define ECH(i,u,pre,next) for(int i=int(pre[u]);i!=-1;i=int(next[i]))

#define MEM(a,v) memset(a,v,sizeof(a))
#define CLR(a,v) FOR(_i##a,0,sizeof(a)/sizeof(a[0])-1) a[_i##a]=v

#define LOOP(a,n)                                               \
    FOR(_i##a,0,(n)-1)                                          \
        OT(a[_i##a]),OT(_i##a!=__i##a?' ':'\n')
#define LOOP2(a,n,m)                                            \
    FOR(_i##a,0,(n)-1) FOR(_j##a,0,(m)-1)                       \
        OT(a[_i##a][_j##a]),OT(_j##a!=__j##a?' ':'\n')
#define LOOPG(G,n,pre,next)                                     \
    FOR(_i##a,0,(n)-1) ECH(_j##a,_i##a,pre,next)                \
        OL(_i##a,G[_j##a].v,G[_j##a].w)

#endif // __MACRO__

#ifndef __BIT__
#define __BIT__

template<class T> inline T lb(T i) {return i&-i;}
template<class T> inline T lc(T i) {return i<<1;}
template<class T> inline T rc(T i) {return i<<1|1;}
template<class T> inline T at(T a,int i) {return a& (T(1)<<i);}
template<class T> inline T nt(T a,int i) {return a^ (T(1)<<i);}
template<class T> inline T s1(T a,int i) {return a| (T(1)<<i);}
template<class T> inline T s0(T a,int i) {return a&~(T(1)<<i);}

#endif // __BIT__

#ifndef __COMPARER__
#define __COMPARER__

const double eps = 1e-8;

inline int cmp(double a,double b=0) {return fabs(b-a)<eps?0:((b-a)<eps?+1:-1);}
template<typename type> inline int cmp(type a,type b=0) {return a==b?0:(b<a?+1:-1);}

template<typename type> inline bool gt(type a,type b) {return cmp(a,b)> 0;}
template<typename type> inline bool ge(type a,type b) {return cmp(a,b)>=0;}
template<typename type> inline bool eq(type a,type b) {return cmp(a,b)==0;}
template<typename type> inline bool ne(type a,type b) {return cmp(a,b)!=0;}
template<typename type> inline bool le(type a,type b) {return cmp(a,b)<=0;}
template<typename type> inline bool ls(type a,type b) {return cmp(a,b)< 0;}

template<typename type> inline type smax(type a,type b) {return gt(a,b)?a:b;}
template<typename type> inline type smin(type a,type b) {return ls(a,b)?a:b;}

#endif // __COMPARER__

const int MAXV = 202;
const int MAXE = 39802;

double x[MAXV],y[MAXV];

double dist(int i,int j)
{
    return sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
}
double angle(int i,int j,int k)
{
    if(i==j) return 0;
    if(j==k) return 0;
    if(i==k) return inf;
    double ans1=(x[j]-x[i])*(x[k]-x[j])+(y[j]-y[i])*(y[k]-y[j]);
    double ans2=sqrt((y[j]-y[i])*(y[j]-y[i])+(x[j]-x[i])*(x[j]-x[i]));
    double ans3=sqrt((y[k]-y[j])*(y[k]-y[j])+(x[k]-x[j])*(x[k]-x[j]));
    return acos(ans1/(ans2*ans3));
}

struct node
{
    int v;
    double w;
}G[MAXE];
int _index,pre[MAXV],next[MAXE];

inline void clear(void)
{
    _index=0;
    MEM(pre,-1);
}
inline void add(int u,int v,double w)
{
    G[_index].v=v;
    G[_index].w=w;
    next[_index]=pre[u];
    pre[u]=_index++;
}

double D;
int n,m,u,v;

deque<int> F,T;
bool inq[MAXV][MAXV];
double dis[MAXV][MAXV];

inline void update(int xx,int yy,int x,int y,double w)
{
    if(cmp(dis[xx][yy],dis[x][y]+w)>0)
    {
        dis[xx][yy]=dis[x][y]+w;
        if(!inq[xx][yy])
        {
            inq[xx][yy]=true;
            if(F.empty()||cmp(dis[xx][yy],dis[F.front()][T.front()])>0)
            {
                F.push_back(xx);
                T.push_back(yy);
            }
            else
            {
                F.push_front(xx);
                T.push_front(yy);
            }
        }
    }
}
inline bool SPFA(int src,int des,int n,double A)
{
    FOR(i,0,n-1) FOR(j,0,n-1)
    {
        inq[i][j]=false;
        dis[i][j]=inf;
    }
    inq[src][src]=true;
    dis[src][src]=0;

    while(!F.empty()) F.pop_front();
    while(!T.empty()) T.pop_front();
    F.push_back(src);
    T.push_back(src);

    while(!F.empty())
    {
        int f=F.front(); F.pop_front();
        int t=T.front(); T.pop_front();
        if(t==des) return true;
        inq[f][t]=false;
        ECH(i,t,pre,next)
        {
            int v=G[i].v;
            double w=G[i].w;
            if(cmp(dis[f][t]+w,D)<=0&&cmp(angle(f,t,v),A)<=0)
            {
                update(t,v,f,t,w);
            }
        }
    }

    return false;
}
inline double bin(int n,double l=0,double r=pi)
{
    double mid,ans=-1;
    while(cmp(l,r)<=0)
    {
        mid=(l+r)/2;
        if(SPFA(0,n-1,n,mid))
        {
            ans=mid;
            r=mid-eps;
        }
        else l=mid+eps;
    }
    return ans;
}

int main()
{
    #ifndef ONLINE_JUDGE
    freopen("Eco-driving.txt","r",stdin);
    #else
    #endif

    while(IN(n,m,D))
    {
        FOR(i,0,n-1) IN(x[i],y[i]);
        clear();
        while(m--)
        {
            IN(u,v);
            add(u-1,v-1,dist(u-1,v-1));
        }
        double ans=bin(n);
        if(cmp(ans,-1)==0) OL("Impossible");
        else printf("%.6f\n",ans*180/pi);
    }

    return 0;
}


你可能感兴趣的:(HOJ 12719 Eco-driving)