我们用dis[i,j]代表到i这个点,用j张票的最短路程,那么我们只需要在SPFA更新

的时候,用dis[i,j]更新dis[p,j]和dis[p,j+1]就行了

/**************************************************************
    Problem:
    User: BLADEVIL
    Language: Pascal
    Result: Accepted
    Time: ms
    Memory: kb
****************************************************************/
 
//By BLADEVIL
type
    rec                         =record
        x, use                  :longint;
    end;
     
var
    n, m, k                     :longint;
    pre, other, len             :array[..] of longint;
    last                        :array[..] of longint;
    l                           :longint;
    dis                         :array[..,..] of longint;
    flag                        :array[..,..] of boolean;
    que                         :array[..] of rec;
    ans                         :longint;
     
function min(a,b:longint):longint;
begin
    if a>b then min:=b else min:=a;
end;
     
procedure connect(x,y,z:longint);
begin
    inc(l);
    pre[l]:=last[x];
    last[x]:=l;
    other[l]:=y;
    len[l]:=z;
end;
     
procedure init;
var
    i                           :longint;
    x, y, z                     :longint;
begin
    read(n,m,k);
    for i:= to m do
    begin
        read(x,y,z);
        connect(x,y,z);
        connect(y,x,z);
    end;
end;
 
procedure main;
var
    h, t, q, p                  :longint;
    cur, ti                     :longint;
    i                           :longint;
     
begin
    filldword(dis,sizeof(dis) div ,maxlongint div );
    dis[,]:=;
    h:=; t:=;
    que[].x:=; que[].use:=;
    while h<>t do
    begin
        h:=h mod +;
        cur:=que[h].x;
        ti:=que[h].use;
        flag[cur,ti]:=false;
        q:=last[cur];
        while q<> do
        begin
            p:=other[q];
            if dis[cur,ti]+len[q]<dis[p,ti] then
            begin
                dis[p,ti]:=dis[cur,ti]+len[q];
                if not flag[p,ti] then
                begin
                    t:=t mod +;
                    que[t].x:=p; que[t].use:=ti;
                    flag[p,ti]:=true;
                end;
            end;
            if ti<k then
            begin
                if dis[cur,ti]+len[q] div <dis[p,ti+] then
                begin
                    dis[p,ti+]:=dis[cur,ti]+len[q] div ;
                    if not flag[p,ti+] then
                    begin
                        t:=t mod +;
                        que[t].x:=p; que[t].use:=ti+;
                        flag[p,ti+]:=true;
                    end;
                end;
            end;
            q:=pre[q];
        end;
    end;
    ans:=maxlongint;
    for i:= to k do ans:=min(ans,dis[n,i]);
    writeln(ans);
end;
 
begin
    init;
    main;
end.
/**************************************************************
    Problem:
    User: BLADEVIL
    Language: Pascal
    Result: Accepted
    Time: ms
    Memory: kb
****************************************************************/
 
//By BLADEVIL
type
    rec                         =record
        x, use                  :longint;
    end;
     
var
    n, m, k                     :longint;
    pre, other, len             :array[..] of longint;
    last                        :array[..] of longint;
    l                           :longint;
    dis                         :array[..,..] of longint;
    flag                        :array[..,..] of boolean;
    que                         :array[..] of rec;
    ans                         :longint;
    st, fin                     :longint;
     
function min(a,b:longint):longint;
begin
    if a>b then min:=b else min:=a;
end;
     
procedure connect(x,y,z:longint);
begin
    inc(l);
    pre[l]:=last[x];
    last[x]:=l;
    other[l]:=y;
    len[l]:=z;
end;
     
procedure init;
var
    i                           :longint;
    x, y, z                     :longint;
begin
    read(n,m,k);
    read(st,fin);
    for i:= to m do
    begin
        read(x,y,z);
        connect(x,y,z);
        connect(y,x,z);
    end;
end;
 
procedure main;
var
    h, t, q, p                  :longint;
    cur, ti                     :longint;
    i                           :longint;
     
begin
    filldword(dis,sizeof(dis) div ,maxlongint div );
    dis[st,]:=;
    h:=; t:=;
    que[].x:=st; que[].use:=;
    while h<>t do
    begin
        h:=h mod +;
        cur:=que[h].x;
        ti:=que[h].use;
        flag[cur,ti]:=false;
        q:=last[cur];
        while q<> do
        begin
            p:=other[q];
            if dis[cur,ti]+len[q]<dis[p,ti] then
            begin
                dis[p,ti]:=dis[cur,ti]+len[q];
                if not flag[p,ti] then
                begin
                    t:=t mod +;
                    que[t].x:=p; que[t].use:=ti;
                    flag[p,ti]:=true;
                end;
            end;
            if ti<k then
            begin
                if dis[cur,ti]<dis[p,ti+] then
                begin
                    dis[p,ti+]:=dis[cur,ti];
                    if not flag[p,ti+] then
                    begin
                        t:=t mod +;
                        que[t].x:=p; que[t].use:=ti+;
                        flag[p,ti+]:=true;
                    end;
                end;
            end;
            q:=pre[q];
        end;
    end;
    ans:=maxlongint;
    for i:= to k do ans:=min(ans,dis[fin,i]);
    writeln(ans);
end;
 
begin
    init;
    main;
end.

bzoj 2662&bzoj 2763 SPFA变形的更多相关文章

  1. BZOJ 4898 [APIO2017] 商旅 | SPFA判负环 分数规划

    BZOJ 4898 [APIO2017] 商旅 | SPFA判负环 分数规划 更清真的题面链接:https://files.cnblogs.com/files/winmt/merchant%28zh_ ...

  2. NOIP2009最优贸易[spfa变形|tarjan 缩点 DP]

    题目描述 C 国有 n 个大城市和 m 条道路,每条道路连接这 n 个城市中的某两个城市.任意两个 城市之间最多只有一条道路直接相连.这 m 条道路中有一部分为单向通行的道路,一部分 为双向通行的道路 ...

  3. bzoj 2662: [BeiJing wc2012]冻结【分层图+spfa】

    死活想不到分层图emmm 基本想法是建立分层图,就是建k+1层原图,然后相邻两层之间把原图的边在上一层的起点与下一层的终点连起来,边权为val/2,表示免了这条边的边权,然后答案就是第0层的s到k层的 ...

  4. BZOJ 2662: [BeiJing wc2012]冻结(最短路)

    这道题和 BZOJ 2763飞行路线 几乎一模一样..然后飞行路线我是1A,这道题WA了4次,我开始怀疑我的智商了.. ---------------------------------------- ...

  5. bzoj 3875 骑士游戏 - spfa - 动态规划

    Description  [故事背景] 长期的宅男生活中,JYY又挖掘出了一款RPG游戏.在这个游戏中JYY会 扮演一个英勇的骑士,用他手中的长剑去杀死入侵村庄的怪兽. [问题描述] 在这个游戏中,J ...

  6. [BZOJ] 2662: [BeiJing wc2012]冻结

    https://www.lydsy.com/JudgeOnline/problem.php?id=2662 第一次写分层图(捂脸) 一开始真的naive地建图了,T到飞起.. 可以省下建图的空间,直接 ...

  7. Bzoj 2662: [BeiJing wc2012]冻结 dijkstra,堆,分层图,最短路

    2662: [BeiJing wc2012]冻结 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 647  Solved: 348[Submit][Sta ...

  8. bzoj 2662 [BeiJing wc2012]冻结——分层图

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2662 这种的都是分层图. #include<iostream> #include ...

  9. BZOJ 1046 上升序列(LIS变形)

    要保证长度为L的序列下标字典序最小,当然要尽量选前面的数. 如何判断前面的数是否满足条件?,只需要知道这个数开头的递增序列的最长长度是多少,如果不小于L,那么必然可以加入这个数.还需判断一下它是否大于 ...

随机推荐

  1. Clean Code 《代码整洁之道》前四章读书笔记

    第一章: 整洁的代码只做好一件事   减少重复代码   提高表达力   提早构建简单抽象   让营地比你来时更干净   第二章:有意义的命名 名副其实:如果名称需要注释来补充,就不算是名副其实.   ...

  2. 【廖雪峰老师python教程】——模块

    使用模块 任何模块代码的第一个字符串都被视为模块的文档注释: 使用__author__变量把作者写进去,这样当你公开源代码后别人就可以瞻仰你的大名: 当我们在命令行运行模块文件时,Python解释器把 ...

  3. Linux-Shell脚本编程-学习-2-Linux基本命令

    接上篇,接着学习Linux下的部分命令,后面的这些命令用到的频率可能没有那么多,不过也是经常需要的. 第一部分:程序监测部分,ps和top top命令可能比较眼熟,所以我们先说ps ps命令最烦人了, ...

  4. CodeForces-1121C System Testing

    题目链接 https://vjudge.net/problem/CodeForces-1121C 题面 Description Vasya likes taking part in Codeforce ...

  5. Word2vec之CBOW

    一.Word2vec word2vec是Google与2013年开源推出的一个用于获取word vecter的工具包,利用神经网络为单词寻找一个连续向量看空间中的表示.word2vec是将单词转换为向 ...

  6. HDU 4431 Mahjong(枚举+模拟)(2012 Asia Tianjin Regional Contest)

    Problem Description Japanese Mahjong is a four-player game. The game needs four people to sit around ...

  7. NO4——并查集

    int find(int x) { int r = x; while(father[r]!=r) r = father[r]; return r; } /* int find(int x) { if( ...

  8. 项目启动报错: No naming context bound to this class loader

    发步项目到本地tomcat,启动后,一直包错:  警告: Failed to retrieve JNDI naming context for container [StandardEngine[Ca ...

  9. EXT.NET各个版本下载地址

    官网下载地址为:http://www.nuget.org/packages/Ext.NET

  10. 【bzoj4750】密码安全 单调栈

    题目描述 模10^9+61 输入 第一行包含一个正整数 T ,表示有 T 组测试数据. 接下来依次给出每组测试数据.对于每组测试数据: 第一行包含一个正整数 n . 第二行包含 n 个非负整数,表示 ...