您的位置:首页 > 其它

usaco2.4.3穿越栅栏(最短路)

2014-07-18 14:52 232 查看
这题一开始就建了一个4维数组,结果交上去超出空间了,郁闷了好一会儿,后来想到,一块地方只可能有四个地方与其有路,所以只需要判断它周围的4块区域就可以了,方法安最短路Dijkstra算法就可以了。至于这个算法的介绍,刘汝佳的太短小精悍了,不建议看,还是附上正常人的代码吧:

//函数返回从节点s到节点e的最短路,共n个节点
long dijk(long s,long e)
{
const long infi=999999999;
 
long dis[n]={0};
bool used[n]={false};
long min,next;
memset(dis,255,sizeof(dis));
dis[s]=0;
 
for(long i=1;i<=n;i++)
{
min=infi;
for(long j=1;j<=n;j++)
if(!used[j] && dis[j]!=-1 && dis[j]<min)
{
min=dis[j];
next=j;
}
if(min!=infi)
{
used[next]=true;
for(long j=1;j<=n;j++)
if(!used[j] && map[next][j]!=-1 && (dis[j]>map[next][j]+dis[next] || dis[j]==-1))
dis[j]=map[next][j]+dis[next];
}
}
 
return dis[e];
}

接下来是这道题的代码:

#include <iostream>

#include <cstdio>

#include <cmath>

#include <cstdlib>

using namespace std;

int map[110][40],w,h;

struct aaaa{int x;int y;}door[2];

void aaa(int x,int y,int k);

int dis[2][110][40];

bool key[2][110][40];

int main()

{

    cin>>w>>h;

    int l1=0;

    char lll;

    scanf("%c",&lll);

    for(int i=1;i<=h;i++){

        char ch,ch1;

        for(int j=1;j<=w;j++){

        scanf("%c%c",&ch1,&ch);

        if(ch==' '){map[i][j]+=8;map[i-1][j]+=2;if(i==1){door[l1].x=i;door[l1++].y=j;}}

        }

        scanf("%c%c",&ch1,&ch);

        for(int j=1;j<=w;j++){

        scanf("%c%c",&ch1,&ch);

        if(ch1==' '){map[i][j]+=4;map[i][j-1]+=1;if(j==1){door[l1].x=i;door[l1++].y=j;}}

        }

        scanf("%c%c",&ch1,&ch);

        if(ch1==' '){door[l1].x=i;door[l1++].y=w;}

    }

    for(int i=1;i<=w+1;i++){

        if(l1==2)break;

        char ch,ch1;

         scanf("%c%c",&ch1,&ch);

        if(ch==' '){door[l1].x=h;door[l1].y=i;}

    }

    for(int i=0;i<=1;i++)

    {

        aaa(door[i].x,door[i].y,i);

    }

    for(int i=1;i<=h;i++)

    for(int j=1;j<=w;j++)

       {

           dis[0][i][j]=min(dis[0][i][j],dis[1][i][j]);

       }

    int kkk=0;

    for(int i=1;i<=h;i++)

        for(int j=1;j<=w;j++)

    {

        if((i!=door[0].x||j!=door[0].y)&&(i!=door[1].x||j!=door[1].y))

            kkk=max(kkk,dis[0][i][j]);

    }

    cout<<kkk+1<<endl;

return 0;

}

void aaa(int x,int y,int k)

{

    aaaa next;

    for(int i=1;i<=h;i++)

        for(int j=1;j<=w;j++)

        dis[k][i][j]=-1;

    dis[k][x][y]=0;

    for(int kk=1;kk<=w*h;kk++)

    {

        int mins=999999;

        for(int i=1;i<=h;i++)

            for(int j=1;j<=w;j++)

            if(!key[k][i][j]&&dis[k][i][j]!=-1&&dis[k][i][j]<mins){

             mins=dis[k][i][j];

             next.x=i;

             next.y=j;

        }

        if(mins!=999999)

        {

            key[k][next.x][next.y]=true;

            for(int j=1;j<=8;j*=2)

            if(j==1)

            {if(!key[k][next.x][next.y+1]&&map[next.x][next.y]&1&&(dis[k][next.x][next.y+1]>dis[k][next.x][next.y]+1||dis[k][next.x][next.y+1]==-1))

                dis[k][next.x][next.y+1]=dis[k][next.x][next.y]+1;}

            else if(j==2)

            {if(!key[k][next.x+1][next.y]&&map[next.x][next.y]&2&&(dis[k][next.x+1][next.y]>dis[k][next.x][next.y]+1||dis[k][next.x+1][next.y]==-1))

                dis[k][next.x+1][next.y]=dis[k][next.x][next.y]+1;}

            else if(j==4)

            {if(!key[k][next.x][next.y-1]&&map[next.x][next.y]&4&&(dis[k][next.x][next.y-1]>dis[k][next.x][next.y]+1||dis[k][next.x][next.y-1]==-1))

                dis[k][next.x][next.y-1]=dis[k][next.x][next.y]+1;}

            else if(j==8)

            {if(!key[k][next.x-1][next.y]&&map[next.x][next.y]&8&&(dis[k][next.x-1][next.y]>dis[k][next.x][next.y]+1||dis[k][next.x-1][next.y]==-1))

                dis[k][next.x-1][next.y]=dis[k][next.x][next.y]+1;}

        }

   }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: