51nod 1326

来源:互联网 发布:天书残卷披风进阶数据 编辑:程序博客网 时间:2024/05/18 02:37

原题链接
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 longusing 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;}
原创粉丝点击