原题链接
road(0,n-1)=road(0, n-1的邻接点x)+edge(x,n-1)*2*k 构成!
选取mod,mod=min( edge(x, n-1) )。
SPFA跑一遍,求出G[u][d],
G[u][d]表示从0出发到达u的路径长度%mod=d的最短路径。
跑完之后,
枚举n-1的邻接点,再枚举d,看能否构造出T。
#include<set>
#include<map>
#include<queue>
#include<cmath>
#include<string>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define debug puts("Infinity is awesome!")
#define mm(a, b) memset(a, b, sizeof(a))
#define LL long long
using namespace std;
const LL Inf=0x3f3f3f3f3f3f3f3f;
const int maxn=55;
const int maxe=105;
const int maxmod=2e4;
int n, m;
LL dist;
struct Edge{
int to, dist, next;
};
Edge edges[maxe];
int head[maxn], ecnt;
LL mod;
void Init(){
memset(head, -1, sizeof head);
ecnt=0;
}
void AddEdge(int u,int v,int d){
edges[ecnt]=Edge{v, d, head[u]};
head[u]=ecnt++;
}
struct Node{
int p;
LL dist;
};
LL G[maxn][maxmod];
void Pre(){
for(int i=0;i<n;i++)
for(int j=0;j<mod;j++)
G[i][j]=Inf;
queue<Node> Q;
Q.push(Node{0, 0LL});
while(!Q.empty()){
Node x=Q.front(); Q.pop();
int u=x.p, d=x.dist;
if(d>G[u][d%mod]) continue;
G[u][d%mod]=d;
for(int i=head[u];i!=-1;i=edges[i].next){
int v=edges[i].to;
int d2=edges[i].dist;
LL newd=d+d2;
if(G[v][newd%mod]>G[u][d%mod]+d2){
G[v][newd%mod]=G[u][d%mod]+d2;
Q.push(Node{v, newd});
}
}
}
}
int main(){
int T;
int cas=0;
int u, v, d;
//printf("%lld\n", Inf);
scanf("%d", &T);
while(T--){
scanf("%d%d%lld", &n, &m, &dist);
mod=2*1e4;
Init();
for(int i=0;i<m;i++){
scanf("%d%d%d", &u, &v, &d);
AddEdge(u, v, d);
AddEdge(v, u, d);
if(u==n-1||v==n-1) mod=min(mod, 2LL*d);
}
//printf("mod=%lld\n", mod);
Pre();
int flag=0;
for(int i=head[n-1];i!=-1&&!flag;i=edges[i].next){
int v=edges[i].to;
int d=edges[i].dist;
for(int j=0;j<mod;j++){
//printf("v=%d j=%d d=%d cost=%lld\n", v, j, d, G[v][j]);
if(G[v][j]<Inf&&(dist-G[v][j])%(2LL*d)==d){
//printf("%lld\n", G[v][j]);
flag=1;
break;
}
}
}
puts(flag?"Possible":"Impossible");
}
return 0;
}