http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1326

1326 遥远的旅途

题目来源: TopCoder
基准时间限制:2 秒 空间限制:131072 KB 分值: 320 难度:7级算法题
收藏
关注
一个国家有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.
Input
多组测试数据,输入的第一行含一个整数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。
Output
每组测试数据一行输出,如果存在题目所述路径输出“Possible”,否则“Impossible”,不含引号。
Input示例
1
3 3 25
0 2 7
0 1 6
1 2 5
Output示例
Possible
 T很大,如果直接bfs暴力的话肯定是不行的。
题解看得也很玄学感觉还是有点不明白这样做的可行性,就是对于T很大的情况肯定要走环才能抵消这么大的路程,
我们不妨以N为结束点,N的入边作为环来延长总路径,假设有一条连接N点的边权值为w,有一条长度为k从1-N的路径,
如果(T-k)%(2*w)==0&&k<=T,我们就可以认定这是有可能的,我一直想要是这个环不在末尾而是处于中间会不会出现很多节点导致T,不过并没有出现,具体的证明我也不会。只能先码上了。
dis[i][j]表示(1->i点的距离%mod)=j的最小距离,mod=2*w,直接跑spfa更新就好了,如果dis[N][T%(2*w)]<=T,说明可能,否则不可能。
用dp表示的话似乎好理解了那么一点,因为边权最大1w,所有的路径长度模完之后最多也就两万种情况。

基本思想:能否在T时刻刚好到达n号点,可选n点的任一入边(q-->n),记录边长ds,看能否在S时刻到达q,且   (T-S)%(2*ds)==0(S<=T)。

然后可以设dp[x][y] 表示到达x点,并且使dp[i][j]%(2*ds)==j 成立的最小时刻。初始化dp[1][0]=0;然后跑SPFA;DP方程dp[k][ (j+dis[i][k])%(2*ds) ] = min { dp[i][j] + dis[i][k] }。

 #include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
struct Edge{int to,w,next;}e[];
int cnt,first[];
long long d[][];
void add(int u,int v,int w)
{
e[cnt].w=w;
e[cnt].to=v;
e[cnt].next=first[u];
first[u]=cnt++;
}
struct node{int u,w;}; bool vis[][];
long long spfa(int N,int mod,long long T)
{
memset(vis,,sizeof(vis));
memset(d,inf,sizeof(d));
queue<node>Q;
Q.push(node{,});
vis[][]=;
d[][]=;
while(!Q.empty()){
node t1=Q.front(); Q.pop();
vis[t1.u][t1.w]=;
for(int i=first[t1.u];i+;i=e[i].next){
Edge x=e[i];
if(d[x.to][(t1.w+x.w)%mod]>d[t1.u][t1.w]+x.w){
d[x.to][(t1.w+x.w)%mod]=d[t1.u][t1.w]+x.w;
if(!vis[x.to][(t1.w+x.w)%mod]){
Q.push(node{x.to,(t1.w+x.w)%mod});
vis[x.to][(t1.w+x.w)%mod]=;
}
}
}
}
return d[N][T%mod];
}
int main()
{
int C,N,M,i,j,k;
long long T;
while(cin>>C){
while(C--){
int a,b,c;
cin>>N>>M>>T;
cnt=;
memset(first,-,sizeof(first));
while(M--){
cin>>a>>b>>c;
a++;b++;
add(a,b,c);
add(b,a,c);
}
bool ok=;
for(i=;i<cnt;i+=)
{
if(e[i].to==N||e[i+].to==N)
{
int w=*e[i].w;
if(spfa(N,w,T)<=T){ok=;break;}
}
}
ok?puts("Possible"):puts("Impossible");
}
}
//system("pause");
return ;
}

51nod 1326 奇妙的spfa+dp的更多相关文章

  1. 【BZOJ1003】1003: [ZJOI2006]物流运输trans SPFA+DP

    Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格 ...

  2. HDU 3499 Flight spfa+dp

    Flight Time Limit : 20000/10000ms (Java/Other)   Memory Limit : 65535/65535K (Java/Other) Total Subm ...

  3. BZOJ 1003 [ZJOI2006]物流运输trans SPFA+DP

    题意:链接 方法:SPFA+DP 解析:挺好的题目.因为数据范围较小所以用这样的方式能够搞,只是也是挺不好想的. 我们定义cost(i,j)表示从第i天走到第j天运用同一种方式的最小花费,然后因为数据 ...

  4. BZOJ2763 [JLOI2011]飞行路线(SPFA + DP)

    题目 Source http://www.lydsy.com/JudgeOnline/problem.php?id=2763 Description Alice和Bob现在要乘飞机旅行,他们选择了一家 ...

  5. BZOJ 1003 物流运输 题解 【SPFA+DP】

    BZOJ 1003 物流运输 题解 Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的 ...

  6. HDU 4433 locker(SPFA+DP)

    题目链接 去年区域赛的题目,早就看过题目了,又是过了好久了... 这题状态转移,一看就知道应该是 线性的那种,不过细节真的不好处理,一直没想出怎么搞,期间也看过题解,好像没太看懂... dp[i][j ...

  7. BZOJ-1003 物流运输trans SPFA+DP

    傻逼错误耗我1h,没给全范围坑我1A.... 1003: [ZJOI2006]物流运输trans Time Limit: 10 Sec Memory Limit: 162 MB Submit: 529 ...

  8. 51nod 1043 幸运号码(数位dp)

    题目链接:51nod 1043 幸运号码 题解:dp[i][j]表示 i 个数和为 j 的总数(包含0开头情况) dp[i][j] = dp[i-1][j-k] i & 1 :这里用滚动数组节 ...

  9. 51nod 1092 回文字符串 (dp)

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1092 这个题是poj-3280的简化版,这里只可以增加字符,设 dp[i ...

随机推荐

  1. Virtualbox报错------>make sure the kernel module has been loaded successfully

    错误描述 很久没有用virtualbox了,今天打算在virtualbox上安装一个Ubuntu系统的时候,新建好Ubuntu后启动的时候,直接报错: Cannot access the kernel ...

  2. 实现num1、num2交换,无中间变量

    num1=num1+num2; num2=num1-num2; num1=num1-num2;

  3. XPath学习

    一.基本语法 1.以 / 斜线开始,该路径表示到一个元素下的绝对路径 2.如果路径以双斜线 // 开头, 则表示选择文档中所有满足双斜线//之后规则的元素(无论层级关系) 3.星号 * 表示选择所有由 ...

  4. beego——session控制

    beego内置了session模块,目前session模块支持的后端引擎包括memory.cookie.file.mysql.redis.couchbase.memcache.postgres, 用户 ...

  5. pyton全栈开发从入门到放弃之数据类型与变量

    一.变量 1 什么是变量之声明变量 #变量名=变量值 age=18 gender1='male' gender2='female' 2 为什么要有变量 变量作用:“变”=>变化,“量”=> ...

  6. linux svn 命令

    windows下的TortoiseSVN是资源管理器的一个插件,以覆盖图标表示文件状态,几乎所以命令都有图形界面支持,比较好用,这里就不多说.主要说说linux下svn的使用,因为linux下大部分的 ...

  7. iOS程序的启动过程介绍

    大家在学习iPhone开发时候,都会写HelloWorld程序.大家一般都是通过向导,生成项目,然后通过模拟器启动应用程序.但是大家知道其背后的启动过程吗?也就是当点击程序图标启动程序开始到退出程序整 ...

  8. Codeforces Round #397 by Kaspersky Lab and Barcelona Bootcamp (Div. 1 + Div. 2 combined) D. Artsem and Saunders

    地址:http://codeforces.com/contest/765/problem/D 题目: D. Artsem and Saunders time limit per test 2 seco ...

  9. GIT使用—安装配置及工作流程

    一.Git 与 SVN 区别 GIT不仅仅是个版本控制系统,它也是个内容管理系统(CMS),工作管理系统等. 1.GIT是分布式的,SVN不是:这是GIT和其它非分布式的版本控制系统,例如SVN,CV ...

  10. 实验一 Linux初步认识

    遇到的困难和心得体会: 1.在操作过程中,有道作业是建立一个opt/forloutest的文件,而我建立了一个 OPT文件,cd OPT,却显示not a directory,通过阅读<linu ...