UVALive7220

1 题意

A是出发点,B是到达点,0是障碍、不可达,1~9是该可达点的分值,玩家要不断将一些可达点变为障碍,然后获得该点的分数,直到A到B没有通路则停止将可达点变为障碍的动作,游戏结束。求最大获取的分是多少。

2 分析

从A和B分别出发,算出到其他点的sum,算出每条通路上减去一个点的分数后的最小值。,然后遍历所有点,而所有可达点之和的分数-(某条通路上减去一个点的分数)最大值就是结果。

3

//WA 1 <<优先级低
//WA 2 MAXN溢出 OR 合成的点需要判断是否可达

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <string>
#include <cstdio>
#include <math.h>
#include <queue>
#include <stack>
#include <deque>
using namespace std;

typedef long long ll;
const int maxn=110;
const int MAXN=0x3f3f3f3f;
char map_zifu[maxn][maxn];
int da[maxn][maxn],db[maxn][maxn];
int dir[4][2]={-1,0,1,0,0,-1,0,1};
bool bj[maxn][maxn];
int n,m,sum,all;
int ax,ay,bx,by;//a - b .
struct Node{
    int x;
    int y;
}na,nb;
bool Check(struct Node n2){
    if(n2.x<0||n2.x>=n||n2.y<0||n2.y>=m)
        return false;
    else
        return true;
}
bool Judge(struct Node n2){
    if(map_zifu[n2.x][n2.y]=='0'){
        return false;
    }
    if((n2.x==na.x&&n2.y==na.y)||(n2.x==nb.x&&n2.y==nb.y))
        return false;
    else
        return true;
}
void Spfa(struct Node n1,int d[][maxn]){
    queue<struct Node> qq;
    memset(bj,false,sizeof(bj));
    struct Node n2;
    qq.push(n1);
    d[n1.x][n1.y]=0;
    bj[n1.x][n1.y]=true;
    while(!qq.empty()){
        n1=qq.front();
        qq.pop();
        bj[n1.x][n1.y]=false;
        for(int i=0;i<4;i++){
            n2.x=n1.x+dir[i][0];
            n2.y=n1.y+dir[i][1];
            if(Check(n2)&&Judge(n2)&&(d[n1.x][n1.y]+(map_zifu[n2.x][n2.y]-'0')<d[n2.x][n2.y])){
                d[n2.x][n2.y]=d[n1.x][n1.y]+map_zifu[n2.x][n2.y]-'0';
                if(!bj[n2.x][n2.y]){
                    qq.push(n2);
                    bj[n2.x][n2.y]=true;
                }
            }
        }
    }
}
int main()
{
    int tt;
    scanf("%d",&tt);
    for(int t=1;t<=tt;t++){
        scanf("%d%d",&n,&m);
        sum=MAXN;//找最短路
        all=0;//所有数之和
        memset(map_zifu,0,sizeof(map_zifu));
        memset(da,MAXN,sizeof(da));
        memset(db,MAXN,sizeof(db));
        for(int i=0;i<n;i++){
            scanf("%s",map_zifu[i]);
            for(int j=0;j<m;j++){
                if(map_zifu[i][j]=='A'){
                    na.x=i;
                    na.y=j;
                }
                else if(map_zifu[i][j]=='B'){
                    nb.x=i;
                    nb.y=j;
                }
                else{
                    all+=(map_zifu[i][j]-'0');
                }
            }
        }
        Spfa(na,da);
        /*
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                cout<<da[i][j]<<endl;
            }
        }
        cout<<"END."<<endl;
        */

        //if(MAXN==da[nb.x][nb.y]){
           // continue;
        //}

        Spfa(nb,db);
        /*
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                cout<<db[i][j]<<endl;
            }
        }
        cout<<"END."<<endl;
        */
        struct Node n2;
        bool flag=0;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                n2.x=i;
                n2.y=j;
                if(!Judge(n2))
                    continue;
                if(da[i][j]==MAXN||db[i][j]==MAXN)
                    continue;
                flag=1;
                sum=min(sum,da[i][j]+db[i][j]-((map_zifu[i][j]-'0')<<1));
                //cout<<"sum: "<<sum<<" i:"<<i<<" j:"<<j<<endl;
            }
        }
        if(!flag){
            printf("Case #%d: 0\n",t);
        }
        else
        printf("Case #%d: %d\n",t,all-sum);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值