USACO2.4 Overfencing(maze1)

        首先想到的就是求图中各点之间的最短路,将每个空和两个出口作为图的点,两个直接相连的点之间的权为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;
}

你可能感兴趣的:(USACO)