BZOJ1579 USACO 2009 Feb Gold 3.Revamping Trails Solution

BZOJ1579 USACO 2009 Feb Gold 3.Revamping Trails Solution

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

标题效果:一个N积分m无向图边。它可以是路径k右边缘值变0,确定此时1-n最短路径长度。

Sol:我以为我们考虑分层图,图复制k+1部分,每间0~k一层。代表在这个时候已经过去“自由边缘”文章编号。

层与层之间的边权值为0且为单向由上层指向下层。

这样我们以0层的1点做单源最短路径。每一层的n点的距离最小值即为答案。

仅仅只是这种点数为O(K*N),边数为O(K*M),比較慢。

我的做法是,对每一层使用heap-dijkstra算法由本层的原点更新这一层的最短路长度。然后显然能够用O(m)的复杂度推知下一层的初始最短路长度。

这样的做法显然空间和时间上均存在较大优势。

Code:

#include <cstdio>
#include <cstring>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;
 
inline int getc() {
    static const int L = 1 << 15;
    static char buf[L], *S = buf, *T = buf;
    if (S == T) {
        T = (S = buf) + fread(buf, 1, L, stdin);
        if (S == T)
            return EOF;
    }
    return *S++;
}
inline int getint() {
    int c;
    while(!isdigit(c = getc()));
    int tmp = c - '0';
    while(isdigit(c = getc()))
        tmp = (tmp << 1) + (tmp << 3) + c - '0';
    return tmp;
}
 
typedef long long LL;
 
#define N 10010
#define M 50010
int n, m, k;
int head[N], next[M << 1], end[M << 1], len[M << 1];
LL dis[2][N];
bool inpath[N];
 
queue<int> q;
 
void addedge(int a, int b, int _len) {
    static int q = 1;
    len[q] = _len;
    end[q] = b;
    next[q] = head[a];
    head[a] = q++;
}
void make(int a, int b, int _len) {
    addedge(a, b, _len);
    addedge(b, a, _len);
}
 
struct Node {
    int lab, dis;
    Node(int _lab = 0, int _dis = 0):lab(_lab),dis(_dis){}
    bool operator < (const Node &B) const {
        return (dis < B.dis) || (dis == B.dis && lab < B.lab);
    }
};
struct Heap {
    Node a[N];
    int top, ch[N];
    Heap():top(0){}
    void up(int x) {
        for(; x != 1; x >>= 1) {
            if (a[x] < a[x >> 1]) {
                swap(ch[a[x].lab], ch[a[x >> 1].lab]);
                swap(a[x], a[x >> 1]);
            }
            else
                break;
        }
    }
    void down(int x) {
        int son;
        for(; x << 1 <= top; ) {
            son=(((x<<1)==top)||(a[x<<1]<a[(x<<1)|1]))?(x<<1):((x<<1)|1);
            if (a[son] < a[x]) {
                swap(ch[a[son].lab], ch[a[x].lab]);
                swap(a[son], a[x]);
                x = son;
            }
            else
                break;
        }
    }
    void insert(Node x) {
        a[++top] = x;
        ch[x.lab] = top;
        up(top);
    }
    Node Min() {
        return a[1];
    }
    void pop() {
        a[1] = a[top];
        ch[a[top--].lab] = 1;
        down(1);
    }
    void change(int x, int to) {
        int ins = ch[x];
        a[ins].dis = to;
        up(ins);
    }
}H;
 
void Dijkstra(bool d) {
    H.top = 0;
    int i, j;
    memset(inpath, 0, sizeof(inpath));
    for(i = 1; i <= n; ++i)
        H.insert(Node(i, dis[d][i]));
    for(i = 1; i <= n; ++i) {
        Node tmp = H.Min();
        H.pop();
        inpath[tmp.lab] = 1;
        for(j = head[tmp.lab]; j; j = next[j]) {
            if (!inpath[end[j]] && dis[d][end[j]] > dis[d][tmp.lab] + len[j]) {
                dis[d][end[j]] = dis[d][tmp.lab] + len[j];
                H.change(end[j], dis[d][end[j]]);
            }
        }
    }
}
 
int main() {
    n = getint();
    m = getint();
    k = getint();
     
    int i, j;
    int a, b, x;
    for(i = 1; i <= m; ++i) {
        a = getint();
        b = getint();
        x = getint();
        make(a, b, x);
    }
     
    int now = 0, last = 1;
     
    memset(dis, 0x3f, sizeof(dis));
    dis[now][1] = 0;
    Dijkstra(now);
    LL ans = dis[now][n];
     
    while(k--) {
        now ^= 1;
        last ^= 1;
        for(i = 1; i <= n; ++i)
            dis[now][i] = dis[last][i];
        for(i = 1; i <= n; ++i)
            for(j = head[i]; j; j = next[j])
                dis[now][end[j]] = min(dis[now][end[j]], dis[last][i]);
        Dijkstra(now);
        if (ans == dis[now][n])
            break;
        ans = dis[now][n];
    }
     
    printf("%lld", ans);
     
    return 0;
}

版权声明:本文博主原创文章。博客,未经同意不得转载。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/117081.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Python实现XML文件解析建议收藏

    1.XML简介XML(eXtensibleMarkupLanguage)指可扩展标记语言,被设计用来传输和存储数据,已经日趋成为当前许多新生技术的核心,在不同的领域都有着不同的应用。它是web

    2021年12月18日
  • 如何画好业务架构图图片_产品业务流程图怎么画

    如何画好业务架构图图片_产品业务流程图怎么画1:什么是业务架构图描述系统对用户提供了什么业务功能。业务架构图是一种表达业务层级和关系的工具。业务架构图可以降低业务系统的复杂度,提高客户理解度,最终给客户最直观的业务体现。2:怎么画出一个好的业务架构图呢?2.1:熟悉功能必须要对功能特别熟悉,明白自己的软件的业务都有哪些,哪些是核心业务,哪些是边缘业务以及他们之间的关系是什么。2.2:分层将业务进行分层,一般来说上层是具体业务,下层比较抽象。下层为上层进行提供服务。在业务架构图中,上下要进行对齐,体现出它们的支持关系。2.3分功能

    2022年10月11日
  • SoundFlower+QuickTime录屏Mac含系统声音[通俗易懂]

    SoundFlower+QuickTime录屏Mac含系统声音[通俗易懂]Mac自带的录屏软件QuickTime不能录系统声音。为此,使用soundflower插件来解决。其原理是添加虚拟声卡,使系统声音输出到该声卡,再将其作为QuickTime录屏的输入。soundflower是一个开源插件,已于2014年停止维护,但其最新版本仍可用于当前版本的mac。同一开发者开发了新软件Loopback,功能类似,多了图形界面。它更好用,但是录制20分钟后会人为加噪,迫使用户购买付费版本($99)????。soundflower最新release:https://github.com/

  • 对比学习、自监督学习的理解「建议收藏」

    对比学习、自监督学习的理解「建议收藏」自监督学习定义:自监督学习主要是利用辅助任务从大规模的无监督数据中挖掘自身的监督信息来提高学习表征的质量,通过这种构造监督信息对网络进行训练,从而可以学习到对下游任务具有价值的表征。辅助任务(pretext):可以认为是一种为达到特定训练任务而设计的间接任务。pretext任务的好处是为了简化原任务的求解,在深度学习中就是避免人工标记样本,实现无监督的语义提取。Pretext任务可以进一步理解为:对目标任务有帮助的辅助任务。主要pretexttask包括:图像旋转、图像着色、图像修复。下游任务:图

  • Java的三种注释

    Java的三种注释Java基础是java初学者的起点,是帮助你从小白入门到精通必学基础课程!为初学者而著!Java300集>>>适合准备入行开发的零基础员学习Java,基于最新JDK13、IDEA平台讲解的,视频中穿插多个实战项目。每一个知识点都讲解的通俗易懂,由浅入深。不仅适用于零基础的初学者,有经验的程序员也可做巩固学习。配套学习:Java初学者入门教程>>>Java注释:单行、多行和文档注释注释是对程序语言的说明,有助于开发者和用户之间的交流,方便理…

  • 什么是tomcat类加载机制_理解分析类面试题

    什么是tomcat类加载机制_理解分析类面试题Tomcat的类加载机制是违反了双亲委托原则的,对于一些未加载的非基础类(Object,String等),各个web应用自己的类加载器(WebAppClassLoader)会优先加载,加载不到时再交给

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号