HDU-3751

HDU CakeMan
D是賣蛋糕的,S是賣蛋糕的人的家,C是城管的家。D要回家按最短路回家,而C要從最短路的必經之路逮住他,求C到D回家的必經之路的最短距離。
知識點:求最短路必經點,將最短路找出來,然後dp_s[i][j]爲到S點的路徑數量,dp_d[i][j]爲到D點的路徑數量,sum爲S點到D點的路徑數量,如果dp_s[i][j]*dp_d[i][j]=sum的話那麼點(i,j)就是最短路必經點。

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const int INF=0x3f3f3f3f;
char map[110][110];
int dis_d[110][110],dis_s[110][110],dis_c[110][110];
int dp_d[110][110],dp_s[110][110];
bool have[110][110],have_c[110][110];
int edge[110][110];
int dx[4]={0,1,0,-1},dy[4]={1,0,-1,0};
int n,m;
struct skt{
    int x,y;
    int dis;
    friend bool operator <(skt a,skt b){
        return a.dis>b.dis;
    }
};
bool can(int x,int y){
    if(x>=1&&x<=n&&y>=1&&y<=m&&map[x][y]!='X')
        return true;
    return false;
}
void bfs_s(int x,int y){
    int i;
    memset(have,0,sizeof(have));
    priority_queue<skt>q;
    skt s;
    s.x=x;s.y=y;s.dis=0;
    q.push(s);
    have[x][y]=true;
    while(!q.empty()){
        skt t=q.top();
        q.pop();
        for(i=0;i<4;i++){
            int tx=t.x+dx[i];
            int ty=t.y+dy[i];
            if(!can(tx,ty)||have[tx][ty])
                continue;
            int op=1;
            have[tx][ty]=true;
            if(map[tx][ty]>='0'&&map[tx][ty]<='9')
                op+=map[tx][ty]-'0';
            dis_s[tx][ty]=t.dis+1;
            skt k;
            k.dis=t.dis+op;
            k.x=tx;k.y=ty;
            q.push(k);
        }
    }
}
void bfs_d(int x,int y){
    int i;
    memset(have,0,sizeof(have));
    priority_queue<skt>q;
    skt s;
    s.x=x;s.y=y;s.dis=0;
    q.push(s);
    have[x][y]=true;
    while(!q.empty()){
        skt t=q.top();
        q.pop();
        for(i=0;i<4;i++){
            int tx=t.x+dx[i];
            int ty=t.y+dy[i];
            if(!can(tx,ty)||have[tx][ty])
                continue;
            int op=1;
            have[tx][ty]=true;
            if(map[tx][ty]>='0'&&map[tx][ty]<='9')
                op+=map[tx][ty]-'0';
            dis_d[tx][ty]=t.dis+op;
            skt k;
            k.dis=t.dis+op;
            k.x=tx;k.y=ty;
            q.push(k);
        }
    }
}
void bfs_c(int x,int y){
    int i;
    priority_queue<skt>q;
    skt s;
    s.x=x;s.y=y;s.dis=0;
    q.push(s);
    have_c[x][y]=true;
    while(!q.empty()){
        skt t=q.top();
        q.pop();
        for(i=0;i<4;i++){
            int tx=t.x+dx[i];
            int ty=t.y+dy[i];
            if(!can(tx,ty)||have_c[tx][ty])
                continue;
            have_c[tx][ty]=true;
            dis_c[tx][ty]=t.dis+1;
            skt k;
            k.dis=dis_c[tx][ty];
            k.x=tx;k.y=ty;
            q.push(k);
        }
    }
}
void dfs_d(int x,int y){
    int i;
    memset(have,0,sizeof(have));
    priority_queue<skt>q;
    skt s;
    s.x=x;s.y=y;
    q.push(s);
    dp_d[x][y]=1;
    have[x][y]=true;
    while(!q.empty()){
        skt t=q.top();
        q.pop();
        for(i=0;i<4;i++){
            int tx=t.x+dx[i];
            int ty=t.y+dy[i];
            if(!can(tx,ty)||!edge[tx][ty])
                continue;
            int op=1;
            //cout<<tx<<" "<<ty<<"h1\n";
            if(map[tx][ty]>='0'&&map[tx][ty]<='9')
                op+=map[tx][ty]-'0';
            //cout<<tx<<" "<<ty<<"h2\n";
            if(dis_d[t.x][t.y]+op==dis_d[tx][ty]){
                dp_d[tx][ty]+=dp_d[t.x][t.y];
            }
            if(!have[tx][ty]){
                have[tx][ty]=true;
                skt k;
                k.x=tx;k.y=ty;
                k.dis=dis_d[tx][ty];
                q.push(k);
            }
        }
    }
}
void dfs_s(int x,int y){
    int i;
    memset(have,0,sizeof(have));
    priority_queue<skt>q;
    skt s;
    s.x=x;s.y=y;
    q.push(s);
    dp_s[x][y]=1;
    have[x][y]=true;
    while(!q.empty()){
        skt t=q.top();
        q.pop();
        for(i=0;i<4;i++){
            int tx=t.x+dx[i];
            int ty=t.y+dy[i];
            if(!can(tx,ty)||!edge[tx][ty])
                continue;
            //cout<<tx<<" "<<ty<<"\n";
            int op=1;
            if(map[t.x][t.y]>='0'&&map[t.x][t.y]<='9')
                op+=map[t.x][t.y]-'0';
            if(dis_s[t.x][t.y]+op==dis_s[tx][ty]){
                dp_s[tx][ty]+=dp_s[t.x][t.y];
            }
            if(!have[tx][ty]){
                have[tx][ty]=true;
                skt k;
                k.x=tx;k.y=ty;
                op=0;
                if(map[tx][ty]>='0'&&map[tx][ty]<='9')
                    op+=map[tx][ty]-'0';
                k.dis=dis_s[tx][ty]+op;
                q.push(k);
            }
        }
    }
}
int main(void){
    int T,i,j,sx,sy,dx,dy,cx,cy;
    cin>>T;
    while(T--){
        scanf("%d%d",&n,&m);
        memset(edge,0,sizeof(edge));
        for(i=1;i<=n;i++){
            for(j=1;j<=m;j++){
                have_c[i][j]=false;
                dp_s[i][j]=0;
                dp_d[i][j]=0;
                dis_s[i][j]=0;
                dis_d[i][j]=0;
                dis_c[i][j]=0;
            }
        }
        for(i=1;i<=n;i++){
            scanf("%s",map[i]+1);
        }
        //cout<<map[3][5]<<"\n";
        for(i=1;i<=n;i++){
            for(j=1;j<=m;j++){
                if(map[i][j]=='S'){
                    bfs_s(i,j);
                    sx=i;sy=j;
                }
                else if(map[i][j]=='D'){
                    bfs_d(i,j);
                    dx=i;dy=j;
                }
                else if(map[i][j]=='C'){
                    bfs_c(i,j);
                    cx=i;cy=j;
                }
            }
        }
        int ans=INF;
        int len=dis_d[sx][sy];
        edge[sx][sy]=edge[dx][dy]=1;
        for(i=1;i<=n;i++){
            for(j=1;j<=m;j++){
                if((i==sx&&j==sy)||(i==dx&&j==dy))
                continue;
                if(dis_d[i][j]+dis_s[i][j]==len){
                    edge[i][j]=1;
                    //cout<<i<<" "<<j<<"\n";
                }
            }
        }
        dfs_d(dx,dy);
        dfs_s(sx,sy);
        int sum=dp_d[sx][sy];
        for(i=1;i<=n;i++){
            for(j=1;j<=m;j++){
                if((i==sx&&j==sy)||(i==dx&&j==dy))
                continue;
                //cout<<dp_d[i][j]<<" "<<dp_s[i][j]<<"\n";
                if(dp_d[i][j]*dp_s[i][j]==sum){
                    //cout<<i<<" "<<j<<"\n";
                    if(have_c[i][j]){
                        ans=min(ans,dis_c[i][j]);
                    }
                }
            }
        }
        if(ans==INF)
            cout<<"-1\n";
        else
            cout<<ans<<"\n";
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章