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

    Description

    一个国家有 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。

    Input

    多组测试数据, 输入的第一行含一个整数 caseT, 表示测试数据个数, 1<=caseT<=5.
    之后有 caseT 组相同结构的测试数据, 每组测试数据构成如下:
    第一行三个整数, N, M, T, 且 2<=N<=50,1<=M<=50, 1<=T<= 10^18).
    之后 M 行, 每行三个整数 Ai,Bi,Di,表示城市 Ai 与 Bi 间有一条双向道路, 且小鹿穿越 这条路要花费 Di 的时间。 其中, 0<= Ai,Bi<N, 1<=Di<=10000。

    Output

    每组测试数据一行输出, 如果存在题目所述路径输出“ Possible”, 否则“ Impossible”, 不含引号。

    Sample Input

    1
    3 3 25
    0 2 7
    0 1 6
    1 2 5

    Sample Output

    Possible

    Hint

    【数据范围】
    对于 10%的数据, caseT=1
    对于另外 20% 的数据, caseT=2
    对于 100%的数据, caseT<=5

     

    基本思想:能否在T时刻刚好到达n号点,可选n点的任一入边(q-->n),记录边长ds,看能否在S时刻到达q,且   (T-S)%(2*ds)==0(S<=T)

    然后可以设dp[x][y] 表示到达x点,并且使dp[i][j]%(2*ds)==j 成立的最小时刻。初始化dp[1][0]=0;然后跑SPFADP方程dp[k][ (j+dis[i][k])%(2*ds) ] = min { dp[i][j] + dis[i][k] }

    几个注意点:

    1:要开 long long,而且切记写在 gi() 之前!

    2:如果没有跑完SPFA就直接 return ,切记先把队列弹空!

    #include <map>
    #include <set>
    #include <cmath>
    #include <ctime>
    #include <queue>
    #include <stack>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define int long long
    #define file(a) freopen(a".in","r",stdin); freopen(a".out","w",stdout);
    
    inline int gi()
    {
        bool b=0; int r=0; char c=getchar();
        while(c<'0' || c>'9') { if(c=='-') b=!b; c=getchar(); }
        while(c>='0' && c<='9') { r=r*10+c-'0'; c=getchar(); }
        if(b) return -r; return r;
    }
    
    const int inf = 1e9+7, N = 65, M = 2e5+7;
    int n,m,t,s,num,f[N],dp[N][M];
    bool b[N][M],fg=0;
    struct node
    {
        int nx,to,ds;
    }da[N<<1];
    struct date
    {
        int x,y;
    };
    queue<date>q;
    
    void link(int fr,int to,int ds)
    {
        da[++num].to=to, da[num].ds=ds, da[num].nx=f[fr], f[fr]=num;
    }
    
    void spfa()
    {
        for(int i=1;i<=n;i++) for(int j=0;j<s;j++) dp[i][j]=t+1, b[i][j]=0;  
      // 切记从 1 开始 b[
    1][0]=1; dp[1][0]=0; date st={1,0}; q.push(st); while(!q.empty()) { date o=q.front(); q.pop(); int x=o.x, y=o.y; b[x][y]=0; for(int i=f[x];i;i=da[i].nx) { int tt=da[i].to, ss=da[i].ds, l=(y+ss)%s; // y 和 dp[x][y] 对于s 同余 if(dp[x][y]+ss<dp[tt][l]) { dp[tt][l]=dp[x][y]+ss; if(!b[tt][l]) { date v={tt,l}; q.push(v); b[tt][l]=1; } } } } } main() { int C=gi(); while(C--) { n=gi(), m=gi(), t=gi(), fg=1; for(int i=0;i<m;i++) { int x=gi()+1, y=gi()+1, z=gi(); link(x,y,z), link(y,x,z); } for(int i=f[n];i;i=da[i].nx) { s=da[i].ds<<1; spfa(); if(dp[n][t%s]<=t) { puts("Possible"); fg=0; break; } } if(fg) puts("Impossible"); for(int i=1;i<=n;i++) f[i]=0; num=0; } return 0; }
  • 相关阅读:
    C#里的async和await的使用
    解决 .NET CORE3.0 MVC视图层不即时编译
    【转】CSS实现自适应分隔线的N种方法
    iscrolljs 看API 回顾以前开发中失误
    自由了-和过去说再见
    js 性能基准测试工具-告别可能、也许、大概这样更快更省
    dom事件不求甚解,色解事件捕获和冒泡
    百度mobile UI组件GMU demo学习1-结构和初始化
    自己收集原生js-2014-2-23
    如何在电脑上测试手机网站(补充)和phonegap
  • 原文地址:https://www.cnblogs.com/y142857/p/6833044.html
Copyright © 2011-2022 走看看