首页 > 其他 > 详细

NOIP 2017 逛公园 记忆化搜索 最短路 好题

时间:2018-11-02 15:05:04      阅读:175      评论:0      收藏:0      [点我收藏+]

Code:

#include<cstdio>        
#include<cstring>    
#include<algorithm>
#include<queue>
#include<string>
using namespace std;
const int maxn=400000+4;
int d[maxn],s, n ,m, mod,tot;
struct SPFA{
	int head[maxn],to[maxn],nex[maxn],val[maxn],cnt;
	void addedge(int u,int v,int c){
		nex[++cnt]=head[u],head[u]=cnt,to[cnt]=v,val[cnt]=c;
	}
	queue<int>Q;
	bool inq[maxn];
	void init(){
		memset(head,0,sizeof(head)), memset(to,0,sizeof(to)), memset(nex,0,sizeof(nex)), memset(val,0,sizeof(val));
		cnt=0;
	}
	void spfa(){
		memset(d,0x3f,sizeof(d));
		memset(inq,false,sizeof(inq));
		d[s]=0,inq[s]=true; Q.push(s);
		while(!Q.empty()){
			int u=Q.front();Q.pop(); inq[u]=false;
			for(int v=head[u];v;v=nex[v]){
				if(d[u]+val[v]<d[to[v]]){
					d[to[v]]=d[u]+val[v];
					if(!inq[to[v]]){ Q.push(to[v]); inq[to[v]]=true; }
				}
			}
		}
	}
}T;
int head[maxn], to[maxn], nex[maxn], val[maxn], cnt;
void addedge(int u,int v,int c){
	nex[++cnt]=head[u], head[u]=cnt, to[cnt]=v, val[cnt]=c;
}
int dp[100007][60];
bool vis[100007][60];
int dfs(int u,int k){
	if(vis[u][k]) return -1;
	if(dp[u][k]!=-1) return dp[u][k];
	vis[u][k]=1;
	int sum=0;
	for(int v=head[u];v;v=nex[v]){
		int tmp=k-(d[to[v]]+val[v]-d[u]);
		if(tmp<0||tmp>tot) continue;
		int delta=dfs(to[v], tmp);
		if(delta==-1) return -1;
		sum=(sum+delta)%mod;		
	}
	if(k==0&&u==n) sum+=1;
	vis[u][k]=0;
	dp[u][k]=sum;
	return sum;
}
int work(){
	memset(dp,-1,sizeof(dp)); 
	memset(head,0,sizeof(head));
	memset(to,0,sizeof(to));
	memset(val,0,sizeof(val));
	cnt=0;
	T.init();
	scanf("%d%d%d%d",&n,&m,&tot,&mod); 
	for(int i=1;i<=m;++i){
		int a,b,c;
		scanf("%d%d%d",&a,&b,&c);
		T.addedge(b,a,c);                         // 返向
		addedge(a,b,c);                           // 正向
	}
	s=n;
	T.spfa();
	int ans=0;
	for(int i=0;i<=tot;++i){
		memset(vis,0,sizeof(vis));
		int aa=dfs(1,i);
		if(aa==-1) return -1;
		ans=(ans+aa)%mod;
	}
	return ans;
}  
int main(){     
	int T;     
	scanf("%d",&T);     
	while(T--) printf("%d\n",work());      
	return 0; 
} 

  

NOIP 2017 逛公园 记忆化搜索 最短路 好题

原文:https://www.cnblogs.com/guangheli/p/9896250.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!