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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值