zoukankan      html  css  js  c++  java
  • free(分层图最短路)(2019牛客暑期多校训练营(第四场))

    示例:

    输入:

    3 2 1 3 1
    1 2 1
    2 3 2

    输出:1

    题意:求s,t最短路,可将k条边权值置零。

    题解:分层图最短路原题

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long int ll;
    const int maxn = 1e5+10;
    const int INF = 0x3f3f3f3f;
    struct State
    {
        // 优先队列的结点结构体
        int v, w, cnt; // cnt 表示已经使用多少次免费通行权限
        State() {}
        State(int v, int w, int cnt) : v(v), w(w), cnt(cnt) {}
        bool operator<(const State &rhs) const
        {
            return w > rhs.w;
        }
    };
    struct node
    {
        int v;
        int w;
        int next;
        /* data */
    } edge[maxn];
    priority_queue<State>pq;
    int n,t,m,k,u,v,w,s;
    int cnt;
    bool vis[maxn][20];
    int dis[maxn][20];
    int head[maxn];
     
    void add(int u,int v,int w)     //链式前向星存边
    {
        edge[cnt] = {v,w,head[u]};
        head[u] = cnt++;
    }
    void dijkstra()
    {
        memset(dis, 0x3f, sizeof(dis));
        dis[s][0] = 0;
        pq.push(State(s, 0, 0)); // 到起点不需要使用免费通行权,距离为零
        while (!pq.empty())
        {
            State top = pq.top();
            pq.pop();
            int u = top.v;
            int nowCnt = top.cnt;
            if (vis[u][nowCnt])
                continue;
            vis[u][nowCnt] = true;
     
            for (int i = head[u]; ~i; i = edge[i].next)
            {
                int v = edge[i].v, w = edge[i].w;
                if (nowCnt < k && dis[v][nowCnt + 1] > dis[u][nowCnt])
                {
                    // 可以免费通行
                    dis[v][nowCnt + 1] = dis[u][nowCnt];
                    pq.push(State(v, dis[v][nowCnt + 1], nowCnt + 1));
                }
                if (dis[v][nowCnt] > dis[u][nowCnt] + w)
                {
                    // 不可以免费通行
                    dis[v][nowCnt] = dis[u][nowCnt] + w;
                    pq.push(State(v, dis[v][nowCnt], nowCnt));
                }
            }
        }
    }
     
    int main()
    {
        memset(head,-1,sizeof (head));
        scanf("%d%d%d%d%d",&n,&m,&s,&t,&k);
        while (m--)
        {
            scanf("%d%d%d",&u,&v,&w);
            add(u, v, w);
            add(v, u, w);
        }
        int ans = INF;
        dijkstra();
        for (int i = 0; i <= k; ++i)
            ans = min(ans, dis[t][i]); // 对到达终点的所有情况取最优值
        cout << ans << endl;
    }
    越努力越幸运,越辛苦越强大。
  • 相关阅读:
    451. Sort Characters By Frequency
    424. Longest Repeating Character Replacement
    68. Text Justification
    44. Wildcard Matching
    160. Intersection of Two Linked Lists
    24. Swap Nodes in Pairs
    93. 递归实现组合型枚举
    98. 分形之城
    97. 约数之和
    96. 奇怪的汉诺塔
  • 原文地址:https://www.cnblogs.com/Aamir-Dan/p/11264215.html
Copyright © 2011-2022 走看看