zoukankan      html  css  js  c++  java
  • HDU5669

    (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦

    Catalog

    Problem:传送门

    Portal

     原题目描述在最下面。

     给你n个点,m组边: a, b ,c ,d ,w.表示点[a,b]与点[c,d]有一条权值为w的无向边。求1-n的最短路。

     有k次把一条边权值变为0的魔法。


    Solution:

     线段树优化建边。对于魔法就在求最短路的时候再加一维处理。

     dp[i][j]表示到点i用了j次魔法的最短路径长度。

    [dp[u][t] = min(dp[u][t],dp[v][t]+w);\ dp[u][t+1] = min(dp[u][t+1],dp[v][t]);//t+1<=k ]


    AC_Code:

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #define lson rt << 1
    #define rson rt << 1 | 1
    using namespace std;
    typedef long long LL;
    
    const LL INF = 0x3f3f3f3f;
    const int MXN = 6e5 + 5;
    const int MXE = 4e6 + 6;
    
    int n, m, k;
    int inde;
    vector<int>vs, vt;
    struct lp{
        int v, nex;
        int w;
        friend bool operator < (const lp &a,const lp &b) {
            return a.w > b.w;
        }
    }cw[MXE], A, B;
    int head[MXN], tot;
    int dis[MXN][12];
    int vis[MXN][12];
    void add_edge(int u,int v,int w) {
        cw[++tot].v = v; cw[tot].w = w; cw[tot].nex = head[u];
        head[u] = tot;
    }
    int seg[MXN][2];
    void build(int id,int l,int r,int rt) {
        seg[rt][id] = ++inde;
        if(l == r) {
            if(id) add_edge(seg[rt][id], l, 0);
            else add_edge(l, seg[rt][id], 0);
            return;
        }
        int mid = (l + r) >> 1;
        build(id, l, mid, lson); build(id, mid + 1, r, rson);
        if(id) {
            add_edge(seg[rt][id], seg[lson][id], 0); add_edge(seg[rt][id], seg[rson][id], 0);
        }else {
            add_edge(seg[lson][id], seg[rt][id], 0); add_edge(seg[rson][id], seg[rt][id], 0);
        }
    }
    void query(int id,int L,int R,int l,int r,int rt) {
        if(L <= l && r <= R) {
            if(id) vs.push_back(seg[rt][id]);
            else vt.push_back(seg[rt][id]);
            return;
        }
        int mid = (l + r) >> 1;
        if(L > mid) query(id, L, R, mid+1, r, rson);
        else if(R <= mid) query(id,L,R,l,mid,lson);
        else {
            query(id,L,mid,l,mid,lson); query(id,mid+1,R,mid+1,r,rson);
        }
    }
    void dij() {
        for(int i = 1; i <= inde; ++i) {
            for(int j = 0; j <= k; ++j) {
                dis[i][j] = INF;
                vis[i][j] = 0;
            }
        }
        dis[1][0] = 0;
        A.v = 1; A.w = 0; A.nex = 0;
        priority_queue<lp> Q;
        Q.push(A);
        while(!Q.empty()) {
            B = Q.top(); Q.pop();
            int u = B.v, t = B.nex;
            if(vis[u][t]) continue;
            vis[u][t] = 1;
            for(int i = head[u]; ~i; i = cw[i].nex) {
                int v = cw[i].v;
                if(dis[v][t] > dis[u][t] + cw[i].w) {
                    dis[v][t] = dis[u][t] + cw[i].w;
                    A.v = v; A.w = dis[v][t]; A.nex = t;
                    Q.push(A);
                }
                if(t < k && dis[v][t+1] > dis[u][t]) {
                    dis[v][t+1] = dis[u][t];
                    A.v = v; A.w = dis[v][t+1]; A.nex = t+1;
                    Q.push(A);
                }
            }
        }
        int ans = INF;
        for(int i = 0; i <= k; ++i) ans = min(ans, dis[n][i]);
        if(ans >= INF) printf("CreationAugust is a sb!
    ");
        else printf("%d
    ", ans);
    }
    int main() {
        int tim;
        scanf("%d", &tim);
        while(tim --) {
            scanf("%d%d%d", &n, &m, &k);
            int a, b, c, d, w;
            memset(head, -1, sizeof(head));
            tot = -1;
            inde = n;
            build(1, 1, n, 1); build(0, 1, n, 1);
            for(int i = 0, ta, tb; i < m; ++i) {
                scanf("%d%d%d%d%d", &a, &b, &c, &d, &w);
                vs.clear(); vt.clear();
                query(1,c,d,1,n,1); query(0,a,b,1,n,1);
                ta = vs.size(); tb = vt.size();
                for(int i = 0; i < tb; ++i) {
                    for(int j = 0; j < ta; ++j) {
                        add_edge(vt[i], vs[j], w);
                    }
                }
                vs.clear(); vt.clear();
                query(1,a,b,1,n,1); query(0,c,d,1,n,1);
                a = vs.size(); b = vt.size();
                for(int i = 0; i < b; ++i) {
                    for(int j = 0; j < a; ++j) {
                        add_edge(vt[i], vs[j], w);
                    }
                }
            }
            dij();
        }
        return 0;
    }
    

    Problem Description:

  • 相关阅读:
    将Python的Django框架与认证系统整合的方法
    将Python的Django框架与认证系统整合的方法
    Python的Asyncore异步Socket模块及实现端口转发的例子
    每天一个linux命令(3):du命令
    每天一个linux命令(2):file 命令
    Ubantu 使用extundelete恢复数据
    ubantu 单用户模式进入系统
    GDB 调试解析
    服务器搭建5 Samba实现文件共享
    服务器搭建4 安装其它库
  • 原文地址:https://www.cnblogs.com/Cwolf9/p/9761939.html
Copyright © 2011-2022 走看看