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”。(不含引号)。
可以参考这道题目#同余最短路# [51nod] 遥远的旅途
注意
连边只需要连接与 n n n相连的最短边跑最短路
其实可以只跑bfs判断是否可行( d i j dij dij的时间复杂度要高)。
假如 t l e tle tle,与 1 1 1连边就好了,蜜汁 A C AC AC
#include
#include
#include
#include
#include
#define mp(x,y,z) make_pair(x,make_pair(y,z))
#define ll long long
#define rr register
using namespace std;
const int N=110,M=20010;
struct node{int y,z,next;}a[N*M];
int n,m,T,tot,head[N]; ll t,d[N][M];
bool flag,v[N][M];
inline int read(){
int p=0; char c=getchar(); while (!isdigit(c)) c=getchar(); while (isdigit(c)) p=(p<<3)+(p<<1)+c-48,c=getchar(); return p;
}
inline void add(int x,int y,int z){a[++tot]=(node){y,z,head[x]}; head[x]=tot;}
inline void dij(int qh){
memset(d,0x3f,sizeof(d)),memset(v,0,sizeof(v));
priority_queue<pair<ll,pair<int,int> > >q;
d[1][0]=0; q.push(mp(0,1,0));
while(q.size()){
int x=q.top().second.first,mx=q.top().second.second; q.pop();
if (v[x][mx]) continue; else v[x][mx]=1;
for(rr int i=head[x];i;i=a[i].next){
int y=a[i].y,my=(a[i].z+mx)%qh;
if (d[y][my]>d[x][mx]+a[i].z) d[y][my]=d[x][mx]+a[i].z,q.push(mp(-d[y][my],y,my));
}
}
}
int main(){
T=read();
while(T--){
flag=tot=0,memset(head,0,sizeof(head)); ll cnt=1e18;
n=read(),m=read(),scanf("%lld",&t);
for(rr int i=1,x,y,z;i<=m;i++) x=read(),y=read(),z=read(),add(x+1,y+1,z),add(y+1,x+1,z);
for(rr int i=head[1];i;i=a[i].next) cnt=min(cnt,1ll*a[i].z*2);
dij(cnt);
if (d[n][t%cnt]<=t) flag=1;
if (flag) printf("Possible\n"); else printf("Impossible\n");
}
}