PAT-GPLT L3-018. 森森美图【最短路+ToleftTest】

起点和终点将矩阵分成两部分,然后让你从两个部分分别求一条最短路。
判断点属于那个部分只要用ToLeftTest就可以了,大于0在直线的左边。第一次求起点到终点,第二次求终点到起点的最短路。起点和终点的分数这样会被计算两次,需要减一下。

#include
using namespace std;

int n,m,inq[120][120];
double s[120][120];
double d[120][120];
int dx[]= {1,-1,0,0,1,-1,1,-1};
int dy[]= {0,0,1,-1,1,-1,-1,1};
struct Point
{
    int x;
    int y;
};

int cross(const Point &a, const Point &b, const Point &p)
{
    return (b.x - a.x)*(p.y - a.y) - (b.y - a.y)*(p.x - a.x);
}

int toLeft(const Point &a, const Point &b, const Point &p)
{
    return cross(a, b, p);
}

double spfa1(int sx,int sy,int ex,int ey)
{
    for(int i=0; i<100; i++)
        for(int j=0; j<100; j++)
        {
            inq[i][j]=0;
            d[i][j]=1e10;
        }
    Point a,b,p;
    a.x=sx;
    a.y=sy;
    b.x=ex;
    b.y=ey;
    d[sx][sy]=s[sx][sy];
    queue<int>qx;
    queue<int>qy;
    qx.push(sx);
    qy.push(sy);
    while(!qx.empty())
    {
        int x=qx.front();
        int y=qy.front();
        qx.pop();
        qy.pop();
        inq[x][y]=0;
        for(int i=0; i<8; i++)
        {
            double w=0;
            int tx=x+dx[i];
            int ty=y+dy[i];
            if(tx<0||tx>=n||ty<0||ty>=m) continue;
            p.x=tx;
            p.y=ty;
            if(toLeft(a,b,p)>0||(tx==ex&&ty==ey))
            {

                //if(s[tx][ty]<0) continue;
                w=s[tx][ty];
                if(i>3) w=w+(s[x][y]+s[tx][ty])*(sqrt(2)-1);
                if(d[tx][ty]>d[x][y]+w)
                {
                    d[tx][ty]=d[x][y]+w;
                    if(inq[tx][ty]==0)
                    {
                        qx.push(tx);
                        qy.push(ty);
                        inq[tx][ty]=1;
                    }
                }
            }
        }
    }
    return d[ex][ey];
}

int main()
{
    cin>>n>>m;
    for(int i=0; ifor(int j=0; jcin>>s[i][j];
        }
    }
    int sx,sy,ex,ey;
    cin>>sy>>sx>>ey>>ex;
    //cin>>sx>>sy>>ex>>ey;
    /*
    int a=__gcd(abs(sx-ex),abs(sy-ey));
    int bx=abs(sx-ex)/a;
    int by=abs(sy-ey)/a;
    int nx,ny;
    nx=sx+bx;
    ny=sy+by;
    while(1)
    {
        if(nx<0||ny<0||nx>=n||ny>=m) break;
        //printf("%d %d\n",nx,ny);
        if(nx==sx&&ny==sy)
        {
            nx+=bx;
            ny+=by;
            continue;
        }
        if(nx==ex&&ny==ey)
        {
            nx+=bx;
            ny+=by;
            continue;
        }
        s[nx][ny]=-1;
        nx+=bx;
        ny+=by;
    }

    nx=sx-bx;
    ny=sy-by;
    while(1)
    {
        if(nx<0||ny<0||nx>=n||ny>=m) break;
        //printf("%d %d\n",nx,ny);
        if(nx==sx&&ny==sy)
        {
            nx-=bx;
            ny-=by;
            continue;
        }
        if(nx==ex&&ny==ey)
        {
            nx-=bx;
            ny-=by;
            continue;
        }
        s[nx][ny]=-1;
        nx-=bx;
        ny-=by;
    }*/
    printf("%.2f\n",spfa1(sx,sy,ex,ey)+spfa1(ex,ey,sx,sy)-s[sx][sy]-s[ex][ey]);
    return 0;
}

你可能感兴趣的:(pta,图论)