zoukankan      html  css  js  c++  java
  • 景驰无人驾驶 1024 编程邀请赛 热爱工作的蒜蒜

    热爱工作的蒜蒜

    众所周知,蒜蒜是一名热爱工作的好员工,他觉得时间就是金钱,做事情总是争分夺秒。

    这天晚上,蒜蒜一个人去吃晚饭。不巧的是,吃完饭以后就开始下雨了,蒜蒜并没有带雨伞出来。但是蒜蒜热爱工作,工作使他快乐,他要尽快赶回去写代码。

    蒜蒜的公司在中关村,中关村这边地形复杂,有很多天桥、地下通道和马路交错在一起。其中,地下通道是可以避雨的,天桥和马路都没办法避。可以把中关村抽象成为 nn 个点的地图(顶点编号为 11 到 nn),其中有 m_1m1​​ 条地下通道,有 m_2m2​​ 条马路或者天桥,其中地下通道的长度为 11。蒜蒜吃饭的地方在 11 点,公司在 nn点。当然,蒜蒜虽然爱工作心切,但是他更不想淋很多雨,同时也不想浪费很多时间。于是他折中了一下——在保证他回到公司所走的路程总和小于等于 LL 的情况下,他希望淋雨的路程和尽量的少。

    请你赶紧帮热爱工作的蒜蒜规划一条路径吧,不要再让他浪费时间。

    输入格式

    第一行输入测试组数 T(1 le T le 20)T(1T20)。

    接下来 TT 组数据。

    每一组数据的第一行输入四个整数 n(2 le n le 100)n(2n100),m_1(0 le m_1 le 50)m1​​(0m1​​50),m_2(0 le m_2 le 5000)m2​​(0m2​​5000),L(1 le L le 10^8)L(1L108​​)。

    接下里 m_1m1​​ 行,每行输入两个整数 a, b(1 le a, b le n)a,b(1a,bn),表示 aa 和 bb 之间有一条地下通道。

    接下里 m_2m2​​ 行,每行输入三个整数 u, v(1 le u, v le n), c(1 le c le 10^6)u,v(1u,vn),c(1c106​​),表示 uu和 vv 之间有一条长度为 cc 的马路或者天桥。

    所有路径都是双向的。

    输出格式

    对于每组数据,如果有满足要求的路径,输出一个整数,表示淋雨的路程长度,否则输出 -11。

    样例输入

    3
    4 2 2 6
    1 2
    2 3
    1 4 5
    3 4 4
    4 2 2 5
    1 2
    2 3
    1 4 5
    3 4 4
    4 2 2 4
    1 2
    2 3
    1 4 5
    3 4 4

    样例输出

    4
    5
    -1

    题目来源

    景驰无人驾驶 1024 编程邀请赛

     

    思路:dp+最短路

    设dp[i][j]:已经走了j条第下路的情况下从出发点到节点i的最短路程(i起点为0)

    那么接下来使用dij计算dp[i][j]即可,则淋雨的路长==min{dp[n-1][i]-i},其中i取遍1,2,...,m1.

    AC代码:

    #define _CRT_SECURE_NO_DEPRECATE
    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<algorithm>
    #include<cstring>
    #include<set>
    #include<string>
    #include<queue>
    using namespace std;
    #define INF 0x3f3f3f3f
    const int N_MAX = 200;
    int n, m1, m2, L;
    struct edge {
        int to, cost;
        edge(int to,int cost):to(to),cost(cost) {}
    };
    struct Node {
        int to, cost, id;//to是当前到达的节点,cost为到达当前点的花费,id是当前已经使用地下通道的数量
        Node(int to,int cost,int id):to(to),cost(cost),id(id) {}
        bool operator < (const Node&b ) const{
            return this->cost > b.cost;
        }
    };
    vector<edge>G_up[N_MAX];
    vector<edge>G_un[N_MAX];
    int dp[N_MAX][N_MAX];//已经走了j条地下通道的情况下从1走到i的最短路径
    
    
    void dijkstra(int s) {
        
        priority_queue<Node>que;
        memset(dp, 0x3f, sizeof(dp));
        dp[s][0] = 0;
        que.push(Node(s,0,0));
        while (!que.empty()) {
            Node p = que.top(); que.pop();
            int v = p.to;
            if (dp[v][p.id] < p.cost)continue;
            for (int i = 0; i < G_up[v].size();i++) {
                edge e = G_up[v][i];
                if (dp[e.to][p.id] > dp[v][p.id] + e.cost) {
                    dp[e.to][p.id] = dp[v][p.id] + e.cost;
                    que.push(Node(e.to,dp[e.to][p.id],p.id));
                }
            }
            if (p.id == m1)continue;//已经走完了所有的地下通道
            for (int i = 0; i < G_un[v].size();i++) {
                edge e = G_un[v][i];
                if (dp[e.to][p.id + 1] > dp[v][p.id] + e.cost) {
                    dp[e.to][p.id + 1] = dp[v][p.id] + e.cost;
                    que.push(Node(e.to,dp[e.to][p.id+1],p.id+1));
                }
            }
    
        }
    }
    
    int main() {
        int t;
        scanf("%d",&t);
        while (t--) {
            scanf("%d%d%d%d", &n, &m1, &m2, &L);
            for (int i = 0; i < n;i++) {
                G_up[i].clear();
                G_un[i].clear();
            }
            for (int i = 0; i < m1;i++) {
                int from, to;
                scanf("%d%d",&from,&to);
                from--, to--;
                G_un[from].push_back(edge(to,1));
                G_un[to].push_back(edge(from, 1));
            }
            for (int i = 0; i < m2;i++) {
                int from, to,cost;
                scanf("%d%d%d",&from,&to,&cost);
                from--, to--;
                G_up[from].push_back(edge(to, cost));
                G_up[to].push_back(edge(from, cost));
            }
            dijkstra(0);
            int res = INF;
            for (int i = 0; i <= m1;i++) {
                if(dp[n-1][i]<=L)
                res = min(res, dp[n - 1][i] - i);
            }
            if (res == INF)res = -1;
            printf("%d
    ",res);
        }
        return 0;
    }
  • 相关阅读:
    0903编写ssh实现远程执行命令 并解决粘包问题
    学习日记0829 IP协议 子网掩码 端口TCP协议的三次握手 四次挥手 套接字socket
    学习日记0828单例 OSI七层协议
    学习日记0827异常处理 元类 自定义元类 自定义元类来实例化类 属性查找顺序
    函数装饰器
    函数对象
    参数
    函数
    文件操作
    字符编码
  • 原文地址:https://www.cnblogs.com/ZefengYao/p/7750662.html
Copyright © 2011-2022 走看看