[国家集训队]飞飞侠

暴力枚举跑三遍堆优化Dijkstra即可

手写堆记得清零

#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
using namespace std;

const int MAXN=155;
const char ch[4]={0,'X','Y','Z'};
const int dx[4]={0,2,3,1},dy[4]={0,3,1,2};

int n,m,siz,tans;
int x[4],y[4];
int v[MAXN][MAXN],t[MAXN][MAXN],ln[MAXN][MAXN],id[MAXN][MAXN];
int ans[4][4];
struct rpg{
    int x,y;
}hp[MAXN*MAXN];

void up(int x)
{
    for(int i=x,j=i>>1;j;i=j,j>>=1){
        if(ln[hp[j].x][hp[j].y]>ln[hp[i].x][hp[i].y]) swap(hp[i],hp[j]),swap(id[hp[i].x][hp[i].y],id[hp[j].x][hp[j].y]);
        else break;
    }return;
}

void ins(rpg x)
{
    hp[++siz]=x;
    id[x.x][x.y]=siz;
    up(siz);
    return;
}

void pop()
{
    id[hp[1].x][hp[1].y]=0;
    hp[1]=hp[siz--];
    id[hp[1].x][hp[1].y]=1;
    for(int i=1,j=2;j<=siz;i=j,j<<=1){
        if(jln[hp[j].x][hp[j].y]) swap(hp[i],hp[j]),swap(id[hp[i].x][hp[i].y],id[hp[j].x][hp[j].y]);
        else break;
    }return;
}

void Dijkstra(rpg s)
{
    memset(ln,0x3f,sizeof(ln));
    memset(hp,0,sizeof(hp));
    memset(id,0,sizeof(id));
    ln[s.x][s.y]=0;ins(s);
    while(siz){
        rpg nw=hp[1];pop();
        int dn=min(n,nw.x+t[nw.x][nw.y]),dm=min(m,nw.y+t[nw.x][nw.y]);
        for(int i=max(nw.x-t[nw.x][nw.y],1);i<=dn;++i){
            for(int j=max(nw.y-t[nw.x][nw.y],1);j<=dm;++j){
                if(abs(nw.x-i)+abs(nw.y-j)>t[nw.x][nw.y]) continue;
                if(ln[i][j]<=ln[nw.x][nw.y]+v[nw.x][nw.y]) continue;
                ln[i][j]=ln[nw.x][nw.y]+v[nw.x][nw.y];
                if(id[i][j]) up(id[i][j]);
                else ins((rpg){i,j});
            }
        }
    }return;
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i){
        for(int j=1;j<=m;++j){
            scanf("%d",&t[i][j]);
        }
    }for(int i=1;i<=n;++i){
        for(int j=1;j<=m;++j){
            scanf("%d",&v[i][j]);
        }
    }for(int i=1;i<=3;++i) scanf("%d%d",&x[i],&y[i]);
    for(int i=1;i<=3;++i){
        Dijkstra((rpg){x[i],y[i]});
        for(int j=1;j<=3;++j) ans[i][j]=ln[x[j]][y[j]];
    }tans=min(ans[1][2]+ans[3][2],min(ans[1][3]+ans[2][3],ans[2][1]+ans[3][1]));
    if(tans>1e9) puts("NO");
    else{
        for(int i=1;i<=3;++i){
            if(ans[dx[i]][i]+ans[dy[i]][i]==tans){
                printf("%c\n%d\n",ch[i],tans);
                return 0;
            }
        }
    }return 0;
}

转载于:https://www.cnblogs.com/AH2002/p/10055519.html

你可能感兴趣的:([国家集训队]飞飞侠)