首先想到的就是求图中各点之间的最短路,将每个空和两个出口作为图的点,两个直接相连的点之间的权为1,同一个点的权为0,其余不直接相连的点之间的权初始化为最大值,然后应用Floyd算法,求出任意两点间的最短距离,然后比较各点到两出口的较短距离,取最大值即可。可恨的是竟然给我说超空间限制了。不过一个4000×4000的int型数组,为何会超空间限制呢?
/*
ID:jzzlee1
PROB:maze1
LANG:C++
*/
//#include <iostream>
#include<cstdio>
#include<cstdlib>
#include<fstream>
#include<cstring>
using namespace std;
ifstream cin("maze1.in");
ofstream cout("maze1.out");
int graph[3820][3820];
char input[210][100];
int name[210][100],count;
int exit1_x,exit1_y,exit2_x,exit2_y;
int w,h;
void add(int x,int y)
{
if(x==1)
{
graph[name[x+1][y]][name[x][y]]=1;
graph[name[x][y]][name[x+1][y]]=1;
}
if(x==2*h+1)
{
graph[name[x-1][y]][name[x][y]]=1;
graph[name[x][y]][name[x-1][y]]=1;
}
if(y==1)
{
graph[name[x][y+1]][name[x][y]]=1;
graph[name[x][y]][name[x][y+1]]=1;
}
if(y==2*w+1)
{
graph[name[x][y-1]][name[x][y]]=1;
graph[name[x][y]][name[x][y-1]]=1;
}
}
int main()
{
int i,j,k;char ch;
cin>>w>>h;
ch=getchar();
for(i=1;i<=2*h+1;i++)
for(j=1;j<=2*w+1;j++)
{
input[i][j]=cin.get();
if(i%2==0&&j%2==0)
name[i][j]=++count;
if(input[i][j]==' '&&(i==1||i==2*h+1||j==1||j==2*w+1) )
if(exit1_x==0&&exit1_y==0)
exit1_x=i,exit1_y=j;
else
exit2_x=i,exit2_y=j;
}
name[exit1_x][exit1_y]=++count;
name[exit2_x][exit2_y]=++count;
for(i=0;i<=count;i++)
for(j=0;j<=count;j++)
{
if(i==j)
graph[i][j]=0;
else
graph[i][j]=1<<20;
}
for(i=2;i<=2*h;i+=2)
for(j=2;j<=2*w;j+=2)
{
if(name[i-2][j]&&input[i-1][j]==' ')//向上
graph[name[i][j]][name[i-2][j]]=1;
if(name[i][j+2]&&input[i][j+1]==' ')//向右
graph[name[i][j]][name[i][j+2]]=1;
if(name[i+2][j]&&input[i+1][j]==' ')//向下
graph[name[i][j]][name[i+2][j]]=1;
if(name[i][j-2]&&input[i][j-1]==' ')//向左
graph[name[i][j]][name[i][j-2]]=1;
}
add(exit1_x,exit1_y);
add(exit2_x,exit2_y);
for(i=1;i<=count;i++)
for(j=1;j<=count;j++)
for(k=1;k<=count;k++)
if(graph[i][k]+graph[k][j]<graph[i][j])
graph[i][j]=graph[i][k]+graph[k][j];
int temp=0,min=0;
for(i=1;i<=count;i++)
{
temp=graph[name[exit1_x][exit1_y]][i]<graph[name[exit2_x][exit2_y]][i]?graph[name[exit1_x][exit1_y]][i]:graph[name[exit2_x][exit2_y]][i];
if(temp>min)
min=temp;
}
cout<<min<<endl;
return 0;
}
实在无法理解为何哪里超空间,愤愤不平之下参考题解改写了一个程序,不过确实比我想的好些,简单不少。
/*
ID:jzzlee1
PROB:maze1
LANG:C++
*/
//#include <iostream>
#include<cstdio>
#include<cstdlib>
#include<fstream>
#include<cstring>
using namespace std;
ifstream cin("maze1.in");
ofstream cout("maze1.out");
const long d[4][2]={0,-1,-1,0,0,1,1,0};
bool flag[210][80];
long ans;
struct node
{
long x,y,len;
}list[10000];
int main()
{
long n,m,i,j,h=1,t=0;
char ch;
cin>>m>>n;
ch=cin.get();
n=2*n+1; m=2*m+1;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
ch=cin.get();
if(ch=='+' || ch=='-' || ch=='|') flag[i][j]=0;
else if(i==1 || i==n || j==1 || j==m){
t++; list[t].x=i; list[t].y=j; list[t].len=1;
flag[i][j]=0;
}
else flag[i][j]=1;
}
ch=cin.get();
}
while(h<=t){
for(i=0;i<4;i++){
long xx=list[h].x+d[i][0],yy=list[h].y+d[i][1];
if(flag[xx][yy]){
t++;
list[t].x=xx; list[t].y=yy;
list[t].len=list[h].len+1;
flag[xx][yy]=0;
}
}
h++;
}
for(long i=1;i<=t;i++)
if(list[i].len>ans)
ans=list[i].len;
ans/=2;
cout<<ans<<endl;
return 0;
}