昨天晚上才写了一道最短路计数,今天就考了…这道题仍然是板子题
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define db double
#define sg string
#define rel(i,x,y) for(int i=(x);i<(y);i++)
#define rep(i,x,y) for(int i=(x);i<=(y);i++)
#define red(i,x,y) for(int i=(x);i>=(y);i--)
#define res(i,x) for(int i=head[x];i;i=nxt[i])
using namespace std;
const int N=2e3+5;
const int Inf=1e18;
const int Mod=1e9+7;
int n,t,id[N][N];
int dis[N*N],vis[N*N],tot[N*N];
int cnt,to[N*N*2],nxt[N*N*2],head[N*N*2];
int dx[4]={0,0,-1,1};
int dy[4]={1,-1,0,0};
struct node {
int num,dis;
bool operator < (const node &a) const {
return a.dis<dis;
}
};
inline int read() {
int x=0;char ch=getchar();bool f=0;
while(ch>'9'||ch<'0'){if(ch=='-')f=1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return f?-x:x;
}
inline int add(int x,int y) {
return x+y>=Mod?x+y-Mod:x+y;
}
bool check(int x,int y) {
return 1<=x&&x<=n&&1<=y&&y<=n;
}
void ins(int x,int y) {
to[++cnt]=y;nxt[cnt]=head[x];head[x]=cnt;
}
void dij(int s) {
priority_queue<node>pq;
for(int i=1;i<=n*n;i++) dis[i]=Inf,vis[i]=tot[i]=0;
dis[s]=0;tot[s]=1;node tmp;tmp.num=s;pq.push(tmp);
while(pq.size()) {
int x=pq.top().num;pq.pop();
if(!vis[x]) {
vis[x]=1;
for(int i=head[x];i;i=nxt[i]) {
int y=to[i],z=1;
if(dis[y]>dis[x]+z) {
dis[y]=dis[x]+z;tot[y]=tot[x];
tmp.num=y;tmp.dis=dis[y];pq.push(tmp);
} else if (dis[y]==dis[x]+z) tot[y]=add(tot[y],tot[x]);
}
}
}
}
void File() {
freopen("school.in","r",stdin);
freopen("school.out","w",stdout);
}
int main() {
// File();
n=read();
rep(i,1,n) rep(j,1,n) id[i][j]=++t;
rep(i,1,n) rep(j,n+1-i,n) rep(k,0,3) if(check(i+dx[k],j+dy[k])) ins(id[i][j],id[i+dx[k]][j+dy[k]]);
dij(n*n-n+1);
if(dis[n]==Inf) puts("0");
else printf("%d\n",tot[n]);
return 0;
}