51nod 1326 遥远的旅途

一个国家有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

题解:  这个题目暴力dp,一定连空间都开不下,但这个已经是凑数模型的唯一状态,没有什么其他办法,所以,一定要想着题目中的其他限制或者说性质。  因为这个是一个图论模型,所以转移就十分有限制,只能走边权,所以我们可以发现要凑出这个数,就一定是先到n号点,然后通过走一条边2*k遍来达到目的,所以我们可以列出式子,(t-dis(1~n))%2*k==0(k为和n号点相连的某条边的边权))转化成t%(2*k)==dis(1~n)%(2*k)。用这个式子,我们就只要看是否存在一条到n的路径,使得路径的边权和%2*k等于一个定值t%(2*k)。  因为这个题目和模数有关,所以我们要把取摸的结果写入状态,dp[i][j]表示处于i节点,从一号点到i号点的花费和%(2*k)(选择的边权)等与k的最小花费,那么转移就是dp[to][(j+quan)%mod]=min(dp[now][j]+quan).  可以说是有限制的凑数问题吧,因为这个题目是一个图,有后效性,所以spfa。

代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#include <queue>
#define MAXN 200
#define MAXN2 20100
#define ll long long
using namespace std;
ll dis[MAXN][MAXN2];
bool have[MAXN][MAXN2];
struct edge{
    int first;
    int next;
    int to;
    int quan;
}a[MAXN*2];
struct node{
    int now,ti;
};
queue<node> q;
int n,m,num=0;ll t,mod;

void addedge(int from,int to,int quan){
    a[++num].to=to;
    a[num].quan=quan;
    a[num].next=a[from].first;
    a[from].first=num;
}

void spfa(){
    memset(dis,127,sizeof(dis));
    memset(have,0,sizeof(have));
    while(!q.empty()) q.pop();
    have[1][0]=1,dis[1][0]=0;
    q.push((node){1,0});
    while(!q.empty()){
        node hh=q.front();q.pop();
        int now=hh.now,t=hh.ti;
        have[now][t]=0;
        for(int i=a[now].first;i;i=a[i].next){
            int to=a[i].to,quan=a[i].quan,tt=(t+quan)%mod;
            if(dis[to][tt]>dis[now][t]+quan){
                dis[to][tt]=dis[now][t]+quan;
                if(!have[to][tt]){
                    have[to][tt]=1;
                    q.push((node){to,tt});
                }
            }
        }
    }
}

void work(){
    scanf("%d%d%lld",&n,&m,&t);
    memset(a,0,sizeof(a));int flag=0;num=0;
    for(int i=1;i<=m;i++){
        int x,y,z;scanf("%d%d%d",&x,&y,&z);x++,y++;
        addedge(x,y,z),addedge(y,x,z);
    }
    for(int i=a[n].first;i;i=a[i].next){
        int quan=a[i].quan;
        mod=quan*2;
        spfa();
        if(dis[n][t%mod]<=t){
            printf("Possible\n");flag=1;
            break;
        }
    }
    if(!flag){
        printf("Impossible\n");
    }
}

int main()
{
    int t;cin>>t;
    while(t--){
        work();
    }
    return 0;
}
时间: 2024-10-15 23:41:48

51nod 1326 遥远的旅途的相关文章

【51Nod】遥远的旅行

Description 一个国家有 N 个城市, 这些城市被标为 0,1,2,...N-1. 这些城市间连有 M 条道路, 每条 道路连接两个不同的城市, 且道路都是双向的. 一个小鹿喜欢在城市间沿着道路自由的穿梭, 初始时小鹿在城市 0 处, 它最终的目的地是城市 N-1 处. 小鹿每在一个城市, 它会选择一条 道路, 并沿着这条路一直走到另一个城市, 然后再重复上述过程. 每条道路会花费小鹿不同 的时间走完, 在城市中小鹿不花时间逗留. 路程中, 小鹿可以经过一条路多次也可以经过一个城市多次

struts2源码探索之初始化(四)

在上一篇文章struts2源码探索之初始化(三)中,已经分析到了创建bootstrap这个容器的最后一步了,调用ContainerBuilder类的create().恩,接下来看这个方法: public Container create(boolean loadSingletons) { ensureNotCreated(); created = true; final ContainerImpl container = new ContainerImpl( new HashMap<Key<?

那些年震撼我们心灵的音乐

由于个人爱好,喜欢听一些纯音乐,因此收集了一些比较好听的纯音乐曲子,其中包括一些音乐大师弹奏的曲子,比如宗次郎.久石让等,还有一些是电影原声配乐,比如加勒比海盗.勇闯夺命岛等经典电影的配乐,还有一些是游戏中的主题音乐,比如魔兽亡灵序曲,还有一些是90年代港剧古装片中常常用到的配乐...总之,这些音乐都或多或少震撼过我们的心灵,现在整理一下奉献给大家. 一.班得瑞.神思者等人的曲子 班得瑞的曲子以清新的曲风为主,听起来有种神游仙界的味道. 这下面18首是个人觉得班得瑞最好听的曲子 1.月光 2.雨

51nod 1273 旅行计划——思维题

某个国家有N个城市,编号0 至 N-1,他们之间用N - 1条道路连接,道路是双向行驶的,沿着道路你可以到达任何一个城市.你有一个旅行计划,这个计划是从编号K的城市出发,每天到达一个你没有去过的城市,并且旅途中经过的没有去过的城市尽可能的多(如果有2条路线,经过的没有去过的城市同样多,优先考虑编号最小的城市),直到所有城市都观光过一遍.现在给出城市之间的交通图T,以及出发地点K,你来设计一个旅行计划,满足上面的条件.例如: (K = 2) 第1天 从2到0 (城市 1 和 0 变成去过的) 第2

[51nod 1288]汽油补给(ST表+单调栈)

[51nod 1288]汽油补给(ST表+单调栈) 题面 有(N+1)个城市,0是起点N是终点,开车从0 -> 1 - > 2...... -> N,车每走1个单位距离消耗1个单位的汽油,油箱的容量是T.给出每个城市到下一个城市的距离D,以及当地的油价P,求走完整个旅途最少的花费.如果无法从起点到达终点输出-1. 分析 贪心考虑,当我们到达一个城市x的时候,我们下一个到的城市应该是在x加满油的情况下,能到达的油价比x低的城市.如果每个加油城市之间的路都这样走,那么最后的价钱一定是最小的.

51nod 1201 整数划分(dp)

题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1201 题解:显然是一道dp,不妨设dp[i][j]表示数字i分成j个一共有几种分法. 那么转移方程式为: dp[i][j] = dp[i - 1][j] + dp[i - 1][j - 1] 表示将i - 1划分为j个数,然后j个数都+1 还是不重复,将i - 1划分为j - 1个数,然后j - 1个数都+1,再加上1这个数. 然后就是j的范围要知道1+2+

安卓旅途之——开发数独(一)

安卓旅途之——开发数独(一) 数独游戏简介 数独游戏,是一种数学智力拼图游戏,是“独立的数字游戏”的简称,源自18世纪末的瑞士,后在美国发展,在日本得以发扬光大. 数独游戏可以训练玩家的逻辑推理能力,不少教育者皆认为数独是锻炼脑筋的好方法. 其规则如下: 1.游戏会从一个部分带有数字的九宫格开始. 在9×9的大九宫格(即3格宽×3格高)方阵里,每一格又细分为一个小九宫格. 2.游戏开始,已给定若干数字,其它宫位留白,玩家需要自己按照逻辑推敲出剩下的空格里是什么数字. 3.填数字时必须满足以下条件

51nod 1138 连续整数的和(数学)

题目描述: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1138 给出一个正整数N,将N写为若干个连续数字和的形式(长度 >= 2).例如N = 15,可以写为1 + 2 + 3 + 4 + 5,也可以写为4 + 5 + 6,或7 + 8.如果不能写为若干个连续整数的和,则输出No Solution. Input 输入1个数N(3 <= N <= 10^9). OutPut 输出连续整数中的第1个数,如果有多

URAL 1326. Bottle Taps(简单的状压dp)

题目不太好读懂,就是先给你一个n代表要从n个物品中买东西,然后告诉你这n个东西的单价,在给你m个集合的情况,就是每个结合中有x件物品,他们合起来买的价格是k.这x件物品依次是:p1--px.之后给你一个kk,表示你要买的物品的编号.让你求出来如何花费最少的钱买到要求的序列. 20,可以状压啊,注意一开始的时候先把单价的状态处理出来...之后就是水题了啊. 1326. Bottle Taps Time limit: 3.0 second Memory limit: 64 MB Programmer