• 跳跳虎回家(国庆10.1模拟赛T2)


    题目:

    【题目描述】

    跳跳虎在外面出去玩忘了时间,现在他需要在最短的时间内赶回家。

    跳跳虎所在的世界可以抽象成一个含有 n 个点的图(点编号从 1 到 n ),跳跳虎现在在 1 号点,跳跳虎的家在 n 号点。

    图上一共有 m 条单向边,通过每条边有固定的时间花费。

    同时,还存在若干个单向传送通道,传送通道也有其时间花费。

    传送通道一般来说比普通的道路更快,但是跳跳虎最多只能使用 k 次。

    跳跳虎想知道他回到家的最小时间消耗是多少。

    【输入格式】

    第一行输入 4 个整数 n,m,q,k 。( n 表示点数,m 表示普通道路的数量,q 表示传送通道的数量,k 表示跳跳虎最多使用 k 次传送通道)

    接下来 m 行每行 3 个整数 u,v,w ,表示有一条从 u 到 v ,时间花费为 w 的普通道路。( 1≤u,v≤n,1≤w≤10)

    接下来 q 行每行 3 个整数 x,y,z ,表示有一条从 x 到 y ,时间花费为 z 的传送通道。( 1≤x,y≤n,1≤z≤10)

    【输出格式】

    输出一行一个整数表示最小时间消耗,如果没法回到家输出 -1 。

    【样例输入】

    5 5 2 1

    1 2 1

    1 3 2

    2 4 2

    3 4 3

    4 5 4

    1 4 1

    2 5 1

    【样例输出】

    2

    【数据规模与约定】

    对于30%的数据,1≤n≤500, 0≤m,q≤2000,k=0;

    对于另外30%的数据,1≤n≤500,0≤m,q≤2000,k=1;

    对于100%的数据,1≤n≤500,0≤m,q≤2000,0≤k≤109

    思路:

      分层建图,定义 dis [ u ][ k ] 表示到结点 u ,共经过 k 条第二类边的最短路。

      显然我们可以以 k 为阶段划分状态,然后就划分成了最短路的子问题。

      dis [ u ][ k ] 可以转移到 dis [ v ][ k ](第一类边)和 dis [ v ][ k+1 ](第二类边)。

      然后就可以用 dijkstar 求最短路 求出答案。

    标程:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<cstdlib>
    #include<stack>
    #include<vector>
    #include<queue>
    #include<deque>
    #include<map>
    #include<set>
    using namespace std;
    #define maxn 1001
    #define INF 0x3f3f3f3f
    int n,m,Q,k;
    int head[maxn],cnt=0;
    int d[maxn][maxn<<1];
    struct hh
    {
        int nex,to,dis,bo;//bo用来判断这条边是否是  
    }t[maxn<<2];
    struct pd//重载(做优先队列用) 
    {
        int u,num,v;//u起始点,num表示这条边之前已经走过了几条传送边 ,v表示 
        bool operator < (const pd &a)const
        {
            return v>a.v;
        } 
    };
    priority_queue<pd> q;
    inline void add(int nex,int to,int dis,int bo)
    {
        t[++cnt].nex=head[nex];
        t[cnt].to=to;
        t[cnt].dis=dis;
        t[cnt].bo=bo;//bo为 0 表示普通的路,为 1 表示传送通道
        head[nex]=cnt;
    }
    inline int read()
    {
        int kr=1,xs=0;
        char ls;
        ls=getchar();
        while(!isdigit(ls))
        {
            if(!(ls^45))
                kr=-1;
            ls=getchar();
        }
        while(isdigit(ls))
        {
            xs=(xs<<1)+(xs<<3)+(ls^48);
            ls=getchar();
        }
        return xs*kr;
    }
    inline void dijkstra()//dijkstra 最短路的双层图模板(和普通最短路模板基本一样)
    {
        q.push((pd){1,0,0});
        d[1][0]=0;
        while(!q.empty())
        {
            pd x=q.top();q.pop();
            if(x.v!=d[x.u][x.num]) continue;
            for(int i=head[x.u];i;i=t[i].nex)
            {
                int v=t[i].to;
                if(d[v][x.num+t[i].bo]>x.v+t[i].dis)//最短路 
                {
                    d[v][x.num+t[i].bo]=x.v+t[i].dis;
                    q.push((pd){v,x.num+t[i].bo,d[v][x.num+t[i].bo]});//存:边权,已走过的传送道路数,距点1 的距离 
                }
            }
        }
    }
    int main()
    {
        freopen("move.in","r",stdin);
        freopen("move.out","w",stdout);
        n=read();m=read();Q=read();k=read();
        int x,y,z;
        for(int i=1;i<=m;i++)
        {
            x=read();y=read();z=read();
            add(x,y,z,0);//存普通的路 
        } 
        for(int i=1;i<=Q;i++)
        {
            x=read();y=read();z=read();
            add(x,y,z,1);//存传送通道 
        }
        memset(d,INF,sizeof(d));
        dijkstra();
        int ans=INF;
        for(int i=0;i<=min(Q,k);i++)
            ans=min(ans,d[n][i]);
        if(ans==INF)//判断是否有路
        {
            printf("-1
    ");return 0;
        }
        printf("%d
    ",ans);
    return 0;
    }
  • 相关阅读:
    ajax获取值的两种方法
    java反射
    idea 方便的设置代码段
    jstl核心标签库
    git遇到的问题 .Git: There is no tracking information for the current branch.
    java使用顺序存储实现队列
    RabbitMQ基本操作
    springboot 如何操作redis
    docker遇到的问题以及docker 操作镜像的基本操作
    教你在 Yii2 中添加全局函数
  • 原文地址:https://www.cnblogs.com/lck-lck/p/9737675.html
Copyright © 2020-2023  润新知