UVA 12295 Optimal Symmetric Paths(spfa+记忆化)

来源:互联网 发布:一念永恒 知乎 编辑:程序博客网 时间:2024/05/07 07:54

题意:
求从左上角到右下角的最短路径数,且要求沿斜线对称
思路:
既然要求对称,所以我们将对称的权值叠加,那么就是求到对角线的最短路径了,通过dp解决方案数

//      whn6325689//      Mr.Phoebe//      http://blog.csdn.net/u013007900#include <algorithm>#include <iostream>#include <iomanip>#include <cstring>#include <climits>#include <complex>#include <fstream>#include <cassert>#include <cstdio>#include <bitset>#include <vector>#include <deque>#include <queue>#include <stack>#include <ctime>#include <set>#include <map>#include <cmath>#include <functional>#include <numeric>#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;#define eps 1e-9#define PI acos(-1.0)#define INF 0x3f3f3f3f#define LLINF 1LL<<62#define speed std::ios::sync_with_stdio(false);typedef long long ll;typedef long double ld;typedef pair<ll, ll> pll;typedef complex<ld> point;typedef pair<int, int> pii;typedef pair<pii, int> piii;typedef vector<int> vi;#define CLR(x,y) memset(x,y,sizeof(x))#define CPY(x,y) memcpy(x,y,sizeof(x))#define clr(a,x,size) memset(a,x,sizeof(a[0])*(size))#define cpy(a,x,size) memcpy(a,x,sizeof(a[0])*(size))#define mp(x,y) make_pair(x,y)#define pb(x) push_back(x)#define lowbit(x) (x&(-x))#define MID(x,y) (x+((y-x)>>1))#define ls (idx<<1)#define rs (idx<<1|1)#define lson ls,l,mid#define rson rs,mid+1,r#define root 1,1,ntemplate<class T>inline bool read(T &n){    T x = 0, tmp = 1;    char c = getchar();    while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();    if(c == EOF) return false;    if(c == '-') c = getchar(), tmp = -1;    while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();    n = x*tmp;    return true;}template <class T>inline void write(T n){    if(n < 0)    {        putchar('-');        n = -n;    }    int len = 0,data[20];    while(n)    {        data[len++] = n%10;        n /= 10;    }    if(!len) data[len++] = 0;    while(len--) putchar(data[len]+48);}//-----------------------------------const int MOD=1000000009;int dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, -1, 1};ll dp[10010];int d[10010],vis[10010],minn;int N,a[111][111];int q[10010];int init(){    scanf("%d",&N);    if(!N)        return 0;    for(int i=0; i<N; i++)        for(int j=0; j<N; j++)            scanf("%d",&a[i][j]);    for(int i=0; i<N; i++)        for(int j=0; j<N-i-1; j ++)            a[i][j]+=a[N-1-j][N-1-i];    return 1;}void spfa(){    int i,j,k,z,next,x,y,xx,yy,front,rear;    for(i=0; i<10010; i++)        d[i]=1000000000;    d[1]=a[0][0];    CLR(vis,0);vis[1]=1;    front=rear=0;    q[rear++]=1;    while(front != rear)    {        z = q[front++];        if(front > N*N)            front=0;        vis[z]=0;        x=(z-1)/N;        y=(z-1)%N;        if(x+y == N-1)            continue;        for(i=0; i<4; i++)        {            xx=x+dx[i];            yy=y+dy[i];            if(xx>=0 && xx<N && yy>=0 && yy<N)            {                next=xx*N+yy+1;                if(d[z]+a[xx][yy] < d[next])                {                    d[next]=d[z]+a[xx][yy];                    if(!vis[next])                    {                        q[rear ++] = next;                        if(rear > N*N)                            rear=0;                        vis[next]=1;                    }                }            }        }    }}ll DP(int cur){    int i,x,y,xx,yy,next;    if(dp[cur]!=-1)        return dp[cur];    x=(cur-1)/N;    y=(cur-1)%N;    if(x+y == N-1)    {        if(d[cur] == minn)            return dp[cur]=1;        else            return dp[cur]=0;    }    dp[cur]=0;    for(int i=0; i<4; i++)    {        xx=x+dx[i];        yy=y+dy[i];        if(xx>=0 && xx<N && yy>=0 && yy<N)        {            next=xx*N+yy+1;            if(d[cur]+a[xx][yy]==d[next])                dp[cur]=(dp[cur]+DP(next))%MOD;        }    }    return dp[cur];}int main(){    while(init())    {        spfa();        minn=1000000000;        for(int i=0; i<N; i++)            if(d[i*N+N-i]<minn)                minn=d[i*N+N-i];        CLR(dp,-1);        printf("%lld\n",DP(1));    }    return 0;}
0 0