HDU 1428 漫步校园

来源:互联网 发布:无敌淘宝王笔趣阁 编辑:程序博客网 时间:2024/05/17 06:02

我队列开小了,改成循环队列就过了,真坑爹....

先SPFA求出各点到终点的最短距离,然后在记忆化搜一遍,记录路径数目,注意在搜的过程中,如果移动点的dis大于等于当前位置,那么就是不可以走的,反之就是可以走的。

#include <stdio.h>#include <cstring>#define inf 1e9using namespace std;int n,t[52][52],dis[52][52];__int64 path[52][52];bool visit[52][52];int h[4]={1,-1,0,0};int g[4]={0,0,1,-1};void SPFA(){    int i,j,k,front=0,rear=0;    int x[3000],y[3000];    memset(visit,0,sizeof(visit));    for(i=1;i<=n;i++)        for(j=1;j<=n;j++)            dis[i][j]=inf;    dis[n][n]=t[n][n];    x[0]=n;y[0]=n;    rear++;    visit[n][n]=1;    while(front!=rear){visit[x[front]][y[front]]=0;        for(i=0;i<4;i++){            int xx=x[front]+h[i];            int yy=y[front]+g[i];            if(xx<1 || xx>n || yy<1 || yy>n)                continue;            if(dis[xx][yy]>dis[x[front]][y[front]]+t[xx][yy]){                dis[xx][yy]=dis[x[front]][y[front]]+t[xx][yy];                if(!visit[xx][yy]){visit[xx][yy]=1;                    x[rear]=xx,y[rear]=yy;rear++;rear=rear%3000;                }            }        }front++;front=front%3000;    }}__int64 dfs(int x,int y){    if(x==n && y==n)        return 1;    if(path[x][y]>=0)        return path[x][y];    __int64 sum=0;    for(int i=0;i<4;i++){        int xx=x+h[i];        int yy=y+g[i];        if(xx<1 || xx>n || yy<1 || yy>n)            continue;        if(dis[xx][yy]>=dis[x][y])            continue;        sum+=dfs(xx,yy);    }    path[x][y]=sum;    return sum;}int main(){    while(scanf("%d",&n)!=EOF){        for(int i=1;i<=n;i++){            for(int j=1;j<=n;j++)                scanf("%d",&t[i][j]);        }        SPFA();        memset(path,-1,sizeof(path));        printf("%I64d\n",dfs(1,1));    }}


 

 

原创粉丝点击