bzoj2143 飞飞侠

来源:互联网 发布:教育收费软件 编辑:程序博客网 时间:2024/04/28 01:42

【题意】

略。

【数据范围】

n<=150,m<=150

【思路】

分层图最短路

【时间复杂度】

O(n^3 log n)

#include<cstdio>#include<cstring>#include<algorithm>#include<queue>#define N 160#define ll long long#define pa(a, b, c, d) (data){a, b, c, d}#define inf 1000000000000000000LLusing namespace std; struct data{ll w; int x, y, z;};const int dx[5]={-1, 0, 0, 0, 1};const int dy[5]={0, -1, 0, 1, 0};struct cc{int x, y;}c[4];int n, m, L[N][N], a[N][N], b[N][N], pos[N][N][310], mnp, flag[N][N][310];ll h[N][N][310], mn, ans[4][4]; bool operator>(data a, data b){return a.w>b.w;}void dijkstra(int S){    priority_queue<data, vector<data>, greater<data> >q;    memset(flag, 0, sizeof(flag));    for(int i=1; i<=n; i++)        for(int j=1; j<=m; j++)            for(int k=0; k<=L[i][j]; k++)h[i][j][k]=inf;    h[c[S].x][c[S].y][0]=0; q.push(pa(0, c[S].x, c[S].y, 0));    data t; int x, y, z, X, Y;    while(!q.empty()){        t=q.top(); q.pop(); x=t.x; y=t.y; z=t.z;        if(flag[x][y][z])continue; flag[x][y][z]=1;        if(flag[c[1].x][c[1].y][0]&&flag[c[2].x][c[2].y][0]&&flag[c[3].x][c[3].y][0])break;        if(z){            for(int i=0; i<=4; i++){                X=x+dx[i]; Y=y+dy[i];                if(1<=X&&X<=n&&1<=Y&&Y<=m&&h[X][Y][z-1]>t.w){                    h[X][Y][z-1]=t.w;                    q.push(pa(h[X][Y][z-1], X, Y, z-1));                }            }        }else{            if(h[x][y][a[x][y]]>t.w+b[x][y]){                h[x][y][a[x][y]]=t.w+b[x][y];                q.push(pa(h[x][y][a[x][y]], x, y, a[x][y]));            }        }    }    for(int i=1; i<=3; i++)ans[S][i]=h[c[i].x][c[i].y][0];} int main(){    scanf("%d%d", &n, &m);    for(int i=1; i<=n; i++)        for(int j=1; j<=m; j++){            scanf("%d", &a[i][j]);            L[i][j]=max(i-1, n-i)+max(j-1, m-j);            a[i][j]=min(a[i][j], L[i][j]);        }    for(int i=1; i<=n; i++)        for(int j=1; j<=m; j++)scanf("%d", &b[i][j]);    for(int i=1; i<=3; i++)scanf("%d%d", &c[i].x, &c[i].y);    dijkstra(1); dijkstra(2); dijkstra(3);    mn=inf; mnp=0;    if(ans[2][1]+ans[3][1]<mn){mn=ans[2][1]+ans[3][1]; mnp=1;}    if(ans[1][2]+ans[3][2]<mn){mn=ans[1][2]+ans[3][2]; mnp=2;}    if(ans[1][3]+ans[2][3]<mn){mn=ans[1][3]+ans[2][3]; mnp=3;}    if(mn==inf)printf("NO");    else printf("%c\n%lld", 'X'+mnp-1, mn);    return 0;}


0 0
原创粉丝点击