长途旅行

【题目描述】

JY是一个爱旅游的探险家,也是一名强迫症患者。现在JY想要在C国进行一次长途旅行,C国拥有n个城市(编号为0,1,2...,n - 1),城市之间有m条道路,可能某个城市到自己有一条道路,也有可能两个城市之间有多条道路,通过每条道路都要花费一些时间。JY从0号城市开始出发,目的地为n – 1号城市。由于JY想要好好参观一下C国,所以JY想要旅行恰好T小时。为了让自己的旅行更有意思,JY决定不在任何一个时刻停留(走一条到城市自己的路并不算停留)。JY想知道是否能够花恰好T小时到达n – 1号城市(每个城市可经过多次)。现在这个问题交给了你。

若可以恰好到达输出“Possible”否则输出“Impossible”。(不含引号)。

【输入格式】

第一行一个正整数Case,表示数据组数。

       每组数据第一行3个整数,分别为n, m, T。

       接下来m行,每行3个整数x, y, z,代表城市x和城市y之间有一条耗时为z的双向边。

【输出格式】

       对于每组数据输出”Possible”或者”Impossible”.

【样例输入】

2

3 3 11

0 2 7

0 1 6

1 2 5

2 1 10000

1 0 1

【样例输出】

Possible

Impossible

【样例解释】

       第一组:0 -> 1 -> 2 :11

       第二组:显然偶数时间都是不可能的。

【数据范围】

       30%:  T <= 10000

另有30%: n <= 5 , m <= 10.

       100%: 2 <= n <= 50 , 1 <= m <= 100 , 1 <= z <= 10000 , 1 <= T <= 10^18 , Case <= 5.

/*
  考试时,暴力+骗分拿了40分。
  正解的思路很神奇,因为我们可能要经过一个环,所以我们设经过一条与0相连的边好几次作为环,那么除了这个环之外,我们要走的路程是j=(T%(2*d)),所以设dis[i][j=t%(2*d)]为走到i点,并且除了环之外,走了(t%(2*d))的最短距离,最后如果dis[n-1][T%(2*d)]<=T,说明可以。
*/
#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
#define N 110
#define M 20010
#define ll long long
using namespace std;
ll cas,n,m,T,head[N],mx,dis[N][M],f[N][M];
struct edge{
    ll v,t,pre;
}e[N*2];
struct node{
    ll x,s;
};
queue<node>q;
ll read(){
    ll num=0;char c=getchar();
    while(c<'0'||c>'9'){c=getchar();}
    while(c>='0'&&c<='9'){num=num*10+c-'0';c=getchar();}
    return num;
}
void Cl(){
    mx=0x7fffffff;
    memset(f,0,sizeof(f));
    memset(head,0,sizeof(head));
    memset(dis,127/3,sizeof(dis));
}
void add(ll i,ll x,ll y,ll z){
    e[i].pre=head[i];
    e[i].v=y;e[i].t=z;
    head[x]=i;
}
void SPFA(){
    dis[1][0]=0;f[1][0]=1;
    q.push((node){1,0});
    while(!q.empty()){
        ll k=q.front().x;
        ll s=q.front().s;
        q.pop();f[k][s]=0;
        for(ll i=head[k];i;i=e[i].pre){
            ll v=e[i].v,y=s+e[i].t;y%=mx;
            if(dis[v][y]>dis[k][s]+e[i].t){
                dis[v][y]=dis[k][s]+e[i].t;
                if(f[v][y]==0){
                    f[v][y]=1;q.push((node){v,y});
                }
            }
        }
    }
}
int main()
{
    //freopen("travel.in","r",stdin);
    //freopen("travel.out","w",stdout);
    cin>>cas;
    while(cas--){
        n=read();m=read();T=read();
        ll u,v,t;Cl();
        for(ll i=1;i<=m;i++){
            u=read();v=read();t=read();
            u++;v++;add(i*2-1,u,v,t);add(i*2,v,u,t);
            if(u==1||v==1)mx=min(mx,t*2);
        }
        if(mx==0x7fffffff){
            printf("Impossible
");continue;
        } 
        SPFA();
        if(dis[n][T%mx]<=T)printf("Possible
");
        else printf("Impossible
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/harden/p/6063324.html