zoukankan      html  css  js  c++  java
  • 逛公园

    看到这题,我们不难想到一个dp,就是设F[i][j]为到达i节点比最短路多了j的方案总数.

    但是我们发现这个状态根本没办法转移:i可以从任何一个有连边的节点转移.(有后效性)

    所以我们倒着跑就好了 ~

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<map>
    #include<queue>
    #include<iostream>
    #include<cmath>
    //#define int long long 
    using namespace std;
    inline int gi(){char tmp=getchar();int flag=1;while(tmp<'0'||tmp>'9'){if(tmp=='-'){flag=-1;tmp=getchar();break;}tmp=getchar();}int ans=0;while(tmp<='9' and tmp>='0') {ans=ans*10+tmp-'0';tmp=getchar();}return ans*flag;}
    inline void write(int x){static int stk[100], top = 0;if (x == 0) { putchar('0'); putchar(' ');return; }if (x < 0) { x = -x; putchar('-'); }while (x) { stk[++top] = x % 10; x /= 10; }while (top) { putchar(stk[top--] + '0'); }putchar(' ');}
    #define line() putchar('
    ');
    #define Mem(Arr,V) memset(Arr,V,sizeof Arr);
    #define Mcpy(Arr,qwq) memcpy(Arr,qwq,sizeof qwq);
    #define max3(a,b,c) max(max(a,b),c)
    #define max4(a,b,c,d) max4(max3(a,b,c),d);
    #define in(a) a=gi()
    #define in2(a,b) in(a),in(b)
    #define in3(a,b,c) in2(a,b),in(c)
    #define in4(a,b,c,d) in3(a,b,c),in(d)
    #define write2(a,b) write(a),write(b)
    #define write3(a,b,c) write2(a,b),write(c)
    #define write4(a,b,c,d) write3(a,b,c),write(d)
    inline void smin(int &x,int y){x=min(x,y);}
    inline void smax(int &x,int y){x=max(x,y);}
    const int N = 1000001;
    struct Edg{
    	int v,w,nxt;
    }Edge[N<<1];int cnt,Head[N];
    inline void Add(int u,int v,int w){Edge[++cnt].v=v;Edge[cnt].w=w;Edge[cnt].nxt=Head[u];Head[u]=cnt;}
    struct Rev{
    	int v,w,nxt;
    }Reverse[N<<1];int cnt1,Pre[N];
    inline void Link(int u,int v,int w){Reverse[++cnt1].v=v;Reverse[cnt1].w=w;Reverse[cnt1].nxt=Pre[u];Pre[u]=cnt1;}
    struct Node{
    	int pos,dis;
    	bool operator > (const Node &x) const {
    		return x.dis<dis;
    	}
    };priority_queue<Node,vector<Node>,greater<Node> >Q;
    bool Vis[N];int Dis[N];
    int n,m,k,p;
    inline void Dijkstra()
    {
    	Mem(Vis,0);Mem(Dis,127);	
    	Q.push(Node{1,0});Dis[1]=0;
    	while(!Q.empty())
    	{
    		int top=Q.top().pos;int dis=Q.top().dis;Q.pop();
    		if(Vis[top]) continue;
    		Vis[top]=1;
    		for(int i=Head[top];i;i=Edge[i].nxt)
    		{
    			int arr=Edge[i].v;
    			if(Edge[i].w+dis<Dis[arr])
    			{
    				Dis[arr]=Edge[i].w+dis;
    				Q.push(Node{arr,Dis[arr]});	
    			} 
    		}
    	}
    }
    int F[N][52];bool Done[N][52];
    int Dfs(int pos,int l)
    {
    	if(l>k or l<0) return 0;
    	if(Done[pos][l]) {Done[pos][l]=0;return -1;}
    	if(F[pos][l]!=-1) return F[pos][l];
    	Done[pos][l]=1;
    	int ans=0;
    	for(int i=Pre[pos];i;i=Reverse[i].nxt)
    	{
    		int arr=Reverse[i].v;
    		int tmp=Dfs(arr,l-Reverse[i].w-Dis[arr]+Dis[pos]);
    		if(tmp==-1)
    		{
    			Done[pos][l]=0;
    			return -1;
    		}
    		ans+=tmp;
    		ans%=p;
    	}
    	Done[pos][l]=0;
    	if(pos==1 and l==0)
    	{
    		F[pos][l]=1;
    		return 1;
    	}
    	return F[pos][l]=ans;
    }
    signed main()
    {
    	#ifndef ONLINE_JUDGE
    		freopen("data.in","r",stdin);
    	#endif
    	int T=gi();
    	while(T--)
    	{
    		cnt=cnt1=0;Mem(Head,0);Mem(Pre,0);
    		in4(n,m,k,p);
    		for(int i=1;i<=m;++i)
    		{
    			int u,v,w;in3(u,v,w);
    			Add(u,v,w);Link(v,u,w);
    		}
    		Dijkstra();
    		// for(int i=1;i<=n;++i)
    			// write(Dis[i]);
    		// return 0;	
    		Mem(F,-1);
    		int ans=0;int flag=0;
    		for(int i=0;i<=k;++i)
    		{
    			int tmp=Dfs(n,i);
    			if(tmp==-1)
    			{
    				puts("-1");
    				flag=1;
    				break;
    			}
    			ans+=tmp;
    			ans%=p;
    		}
    		if(!flag)
    		{
    			write(ans);line();
    		}
    	}
    }
    
  • 相关阅读:
    Memcache相关面试题
    Memcache使用场景
    php链接memcache操作
    永久数据被踢现象
    linux 压缩/解压命令大全
    Linux系统信息查看命令大全
    bundle update: env: ruby_executable_hooks: No such file or directory
    Pod::Executable pull
    Android签名机制:生成keystore、签名、查看签名信息
    Difference between 2>&-, 2>/dev/null, |&, &>/dev/null and >/dev/null 2>&1
  • 原文地址:https://www.cnblogs.com/guodongLovesOi/p/12210071.html
Copyright © 2011-2022 走看看