zoukankan      html  css  js  c++  java
  • 51Nod 1326 遥远的旅途

    题目描述:
    一个国家有N个城市,这些城市被标为0,1,2,...N-1。这些城市间连有M条道路,每条道路连接两个不同的城市,且道路都是双向的。一个小鹿喜欢在城市间沿着道路自由的穿梭,初始时小鹿在城市0处,它最终的目的地是城市N-1处。小鹿每在一个城市,它会选择一条道路,并沿着这条路一直走到另一个城市,然后再重复上述过程。每条道路会花费小鹿不同的时间走完,在城市中小鹿不花时间逗留。路程中,小鹿可以经过一条路多次也可以经过一个城市多次。给定城市间道路的信息,问小鹿是否有一种走法,从城市0出发到达城市N-1时,恰好一共花费T个单位的时间。如果存在输出“Possible”,否则输出“Impossible”。
    注意,小鹿在整个过程中可以多次经过城市N-1,只要最终小鹿停在城市N-1即可。
    例如样例中小鹿的行程可以是0->1->2->0->2.

    解题报告:
    用时:1h30min,1TLE
    这题首先要明白,到终点至少要经过一条n的出边,所以如果可行,一定是将某一条出边走很多次,然后再到达终点,即 (2*w+j==T),所以只要 (j=Tmod2*w) 存在即可,所以我们枚举每一条出边,然后跑spfa ,看 (f[n][j]) 是否存在即可,我们定义 (f[i][j]) 表示到达了(i)这个点 走过的距离(s mod2*w)(j)的最小时间,因为要保证到达n后时间(leq T),所以我们要使得(f[n][j])尽量小,做spfa即可

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #define RG register
    #define il inline
    #define iter iterator
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    using namespace std;
    typedef long long ll;
    const int N=55,M=1000005;
    int q[M][2],mod=M,n,m,head[N],to[N<<1],dis[N<<1],nxt[N<<1],num=0,mo;
    ll TT,f[N][20005];bool vis[N][20005];
    void link(int x,int y,int z){
    	nxt[++num]=head[x];to[num]=y;dis[num]=z;head[x]=num;
    }
    void spfa(){
    	int x,u,disp,t=0,sum=1,now;q[sum][0]=1;q[1][1]=0;
    	memset(vis,0,sizeof(vis));vis[1][0]=true;
    	memset(f,127/3,sizeof(f));f[1][0]=0;
    	while(t!=sum){
    		t++;if(t==mod)t=0;x=q[t][0];now=q[t][1];
    		if(f[n][TT%mo]<=TT)return ;
    		for(int i=head[x];i;i=nxt[i]){
    			u=to[i];
    			disp=(now+dis[i])%mo;
    			if(f[x][now]+dis[i]<f[u][disp]){
    				f[u][disp]=f[x][now]+dis[i];
    				if(!vis[u][disp]){
    					vis[u][disp]=true;sum++;if(sum==mod)sum=0;
    					q[sum][0]=u;q[sum][1]=disp;
    				}
    			}
    			vis[x][now]=false;
    		}
    	}
    }
    void Clear(){
    	memset(head,0,sizeof(head));num=0;
    }
    void work()
    {
    	Clear();
    	int x,y,z;
    	cin>>n>>m>>TT;
    	for(int i=1;i<=m;i++){
    		scanf("%d%d%d",&x,&y,&z);
    		x++;y++;link(x,y,z);link(y,x,z);
    	}
    	for(int i=head[n];i;i=nxt[i]){
    		mo=dis[i]<<1;
    		spfa();
    		if(f[n][TT%mo]<=TT){
    			puts("Possible");
    			return ;
    		}
    	}
    	puts("Impossible");
    }
    
    int main()
    {
    	int T;cin>>T;
    	while(T--)work();
    	return 0;
    }
    
    
  • 相关阅读:
    Django框架基础之序列化
    资产采集
    CMDB
    数据库--三层架构
    Django 项目一补充
    评论楼
    图片预览
    验证码
    如何使用C/C++动态库与静态库中的宏
    Matlab 直线方程、采样函数
  • 原文地址:https://www.cnblogs.com/Yuzao/p/7588425.html
Copyright © 2011-2022 走看看