「NOIP模拟」上学【最短路计数】

在这里插入图片描述

昨天晚上才写了一道最短路计数,今天就考了…这道题仍然是板子题

#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;
}

猜你喜欢

转载自blog.csdn.net/yanzhenhuai/article/details/83541469