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);
}
}