【51nod1326】遥远的旅途
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.
多组测试数据,输入的第一行含一个整数caseT,表示测试数据个数,1<=caseT<=3.
之后有caseT组相同结构的测试数据,每组测试数据构成如下:
第一行三个整数,N,M,T,且2<=N<=50,1<=M<=50,1<=T<=1,000,000,000,000,000,000(即10^18).
之后M行,每行三个整数Ai,Bi,Di,表示城市Ai与Bi间有一条双向道路,且小鹿穿越这条路要花费Di的时间。其中,0<=Ai,Bi< N,1<=Di<=10000。
Solution
我们想想最简单的解法。设出f[i][j]表示当前走到第i个点花费j的时间是否可行。这样空间显然承受不了。
于是我们改变一下思路。我们发现,假设从起点走到终点的有一条路径的长度为a,假设它再往一条与终点相连的长为w的路径反复走无数次后使路径长度到达了T,那么一定满足T-a==0(%2*w),即T(%2 *w)==a(%2 *w)。所以我们枚举一条与终点相连的长为w的路径,设出f[i][j]表示当前到了i点,走的距离f[i][j]最小且满足f[i][j]%(2*w)=j,做spfa即可,时间复杂度O(40000NM40000N M)。
解释一下
有人可能会问,万一我从起点走到一半在一段上反复走,最后才一路走到终点呢?没关系,因为dp已经考虑了这种情况,即在spfa中走回自己的父亲,因为要保证f[i][j]尽量小,所以假设儿子的f[i][(j+cost[k])%2*w]由父亲f[i][j]更新,而儿子的f[i][(j+cost[k])%2*w]又可以更新父亲的f[i][(j+2*cost[k])%2*w],那这样是允许更新的。
Code
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn=2e4+5,maxn1=55;
ll f[maxn1][maxn],value[maxn],s;
int bz[maxn1][maxn],next[maxn],last[maxn],first[maxn],v[maxn*maxn1*2][2];
int n,i,t,j,k,l,x,y,z,m,num;
void lian(int x,int y,int z){
last[++num]=y;next[num]=first[x];first[x]=num;value[num]=z;
}
void spfa(int p){
int i=0,j=1,t,k,x,y;v[1][0]=1;bz[1][0]=1;
for (k=1;k<=n;k++)
for (t=0;t<p;t++)
f[k][t]=s+1;
f[1][0]=0;
while (i<j){ x=v[++i][0];y=v[i][1];
for (t=first[x];t;t=next[t]){ if (f[x][y]+value[t]>=f[last[t]][(y+value[t])%p]) continue;
f[last[t]][(y+value[t])%p]=f[x][y]+value[t];
if (!bz[last[t]][(y+value[t])%p]) v[++j][0]=last[t],v[j][1]=(y+value[t])%p,bz[v[j][0]][v[j][1]]=1;
}
bz[x][y]=0;
}
}
int main(){
// freopen("data.in","r",stdin);
scanf("%d",&l);
while (l){l--;memset(first,0,sizeof(first));num=0;
scanf("%d%d%lld",&n,&m,&s);
for (i=1;i<=m;i++)
scanf("%d%d%d",&x,&y,&z),x++,y++,lian(x,y,z),lian(y,x,z);
k=0;
for (t=first[n];t;t=next[t]){ spfa(2*value[t]);
if (f[n][s%(2*value[t])]<=s){ printf("Possible\n");k++;break;
}
}
if (!k)printf("Impossible\n");
}
}
【51nod1326】遥远的旅途相关推荐
- 51nod1326 遥远的旅途(spfa+dp)
题意: 给出一个无向图,问从1到n是否存在一条长度为L的路径. n,m<=50,1<=路径长度<=10000,L<=10^18 思路: 改变一下思路,我们发现,假设从起点1走到 ...
- [51nod1326]遥远的旅途
Description 一张有n个点,m条变的无向图,每条边有边权. 在0时刻有一个人在点1,每一次他走过一条边,消耗的时间为这条边的边权,而不能停留在原地. 现在他想知道是否存在一种方案使得他在T时 ...
- 51nod 1326 遥远的旅途
题意 一个国家有N个城市,这些城市被标为0,1,2,-N-1.这些城市间连有M条道路,每条道路连接两个不同的城市,且道路都是双向的.一个小鹿喜欢在城市间沿着道路自由的穿梭,初始时小鹿在城市0处,它最终 ...
- 【51nod 1326】遥远的旅途【最短路】
题目: 题目链接:http://www.51nod.com/Challenge/Problem.html#problemId=1326 给出一张nnn个点mmm条边的无向图,询问是否有一条从1到nnn ...
- [51Nod 1326]:遥远的旅途
传送门 这个题的思路就是个dp,不过是在模意义下的dp 我们来设计一个dp[i][j],代表在i这个点,当前路径长度%mod==j,的最小路径长度 我们枚举终点周围的每一条边x,然后mod=2*x,跑 ...
- 【51 Nod 1326】遥远的旅途
Description 一个国家有N个城市,这些城市被标为0,1,2,-N-1.这些城市间连有M条道路,每条道路连接两个不同的城市,且道路都是双向的.一个小鹿喜欢在城市间沿着道路自由的穿梭,初始时小鹿 ...
- #同余最短路# [51nod] 遥远的旅途
题目 http://www.51nod.com/Challenge/Problem.html#problemId=1326 解题思路 我们要使到nnn的时间恰好为ttt,那么必然存在一个环,在到达了某 ...
- 51nod 1326 遥远的旅途 最短路建模
题意 给出一个无向图,问从1到n是否存在一条长度为L的路径. n,m<=50,1<=路径长度<=10000,L<=10^18 分析 考虑枚举起点的每一条出边,设其权值为w,那么 ...
- 【51Nod】-1326 遥远的旅途
Description 一个国家有 N 个城市, 这些城市被标为 0,1,2,...N-1. 这些城市间连有 M 条道路, 每条 道路连接两个不同的城市, 且道路都是双向的. 一个小鹿喜欢在城市间沿着 ...
最新文章
- ubuntu16.04 安装网易云音乐
- 按钮滑动隐藏,停止滑动显示的动画
- Django URL
- sklear多项式回归
- new失败跟踪函数_WinDbg预览时间线:调试器中的时间线可以允许用户记录跟踪
- mfc获取子窗口句柄_前端设计-JavaScript中父窗口与子窗口间的通信
- 【CH5105】Cookies
- 图解3种常见的深度学习网络结构:FC、CNN、RNN
- 如何在软件发布计划中自动化语义化版本与变更日志
- BZOJ 1567: [JSOI2008]Blue Mary的战役地图 矩阵二维hash
- CSS animation 与 transition 有何区别?
- error: 'NULL' was not declared in this scope
- C#中 String 格式的日期时间 转为 DateTime
- 开源SignalR-Client-CPP使用总结
- php windows vld,PHP之opcode及VLD使用
- XTTS,又一个值得你重视的Oracle数据库迁移升级利器
- python文本发音_python3 - 文本读音器
- RK3399 Debian 制作xxx.deb
- bzoj 3944: Sum 杜教筛
- kk-anti-reptile——Spring Boot 反爬虫,防止接口盗刷