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;
    }
    越努力越幸运,越辛苦越强大。
  • 相关阅读:
    vmware-tools安装
    UBUNTU 安装教程
    CANO入门(三)
    CANOE入门(二)
    CANOE入门(一)
    ubuntu 常见错误--Could not get lock /var/lib/dpkg/lock
    vmware-tools安装
    root权限
    ARM嵌入式开发中的GCC内联汇编__asm__
    OpenCV3.1.0+VS2015开发环境配置
  • 原文地址:https://www.cnblogs.com/Aamir-Dan/p/11264215.html
Copyright © 2011-2022 走看看