P4568 [JLOI2011] 飞行路线

news/发布时间2024/5/17 14:43:30

分层图的板子题

代码

#include <bits/stdc++.h>
#define R(x) x=read()
#define fi first
#define se second
using namespace std;typedef pair<int,int> PII;
const int N = 1e4, M = 5e5;inline int read()
{int x = 0, f = 1;char ch = getchar();while(ch < '0' || ch > '9'){if(ch == '-') f = -1;ch = getchar();}while(ch >= '0' && ch <= '9'){x=x*10+ch-'0';ch=getchar();}return x*f;
}struct EdgeElement{int toP, val, ne;
}edges[M*11+5];int h[N*11+5];
int n, m, k, s, t;
int idx;inline void add(int a, int b, int c)
{edges[++idx].toP = b;edges[idx].ne = h[a];edges[idx].val = c;h[a] = idx;
}inline void addDouble(int a, int b, int c)
{add(a, b, c);add(b, a, c);
}bool vis[N*11 + 5];
int dis[N*11 + 5];int DJ()
{priority_queue<PII, vector<PII>, greater<PII> > Q;memset(dis, 0x3f, sizeof(dis));dis[s] = 0;Q.push(make_pair(0, s));while(Q.size()){PII t = Q.top();Q.pop();if(vis[t.se])continue;for(int i = h[t.se]; i; i = edges[i].ne){int j = edges[i].toP;if(dis[j] > dis[t.se] + edges[i].val){dis[j] = dis[t.se] + edges[i].val;Q.push(make_pair(dis[j], j));}}vis[t.se] = 1;}return dis[t + n*k];
}int main()
{// spots: 0~n-1
    R(n);R(m);R(k);R(s);R(t);for(int i = 1; i <= m; i++){int a, b, c;R(a);R(b);R(c);addDouble(a, b, c);for(int j = 1; j <= k; j++){addDouble(a + j * n, b + j * n, c);add(a + (j - 1) * n, b + j * n, 0);add(b + (j - 1) * n, a + j * n, 0);}}// attention!// additional operations about Tfor(int i = 1; i <= k; i++)add(t + (i-1)*n, t + i*n, 0);printf("%d\n", DJ());return 0;
}

细节

1.插入不同层之间的节点时,只能插入单向边,不能插双向边,以样例为例:

 如果在不同层之间插入的是双向边,那就可以从起点走免费点到下一层,然后又走免费边回来……

最后零成本到达终点。

2.边数M的确定

起初我是这样算M的:

题目中给的m上限是5e4,先乘以二,然后又因为要加上十层图,再乘以11.

for(int i = 1; i <= m; i++){int a, b, c;R(a);R(b);R(c);addDouble(a, b, c);for(int j = 1; j <= k; j++){addDouble(a + j * n, b + j * n, c);add(a + (j - 1) * n, b + j * n, 0);add(b + (j - 1) * n, a + j * n, 0);}}

我们可以看到,这里一次加了五条边,所以要再乘以5

3.终点的确定

for(int i = 1; i <= k; i++)add(t + (i-1)*n, t + i*n, 0);

因为我们这里把每一层的终点都连在一起了,所以可以直接把T+n*k作为终点;

如果没有进行这个操作的话,那就需要遍历每一层,dis[T+n*i]取min。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ulsteruni.cn/article/04037634.html

如若内容造成侵权/违法违规/事实不符,请联系编程大学网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

MyBatis动态SQL

MyBatis动态SQL 动态SQL简介 动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦…

Java 中文官方教程 2022 版(十四)

原文:docs.oracle.com/javase/tutorial/reallybigindex.html设置包版本信息原文:docs.oracle.com/javase/tutorial/deployment/jar/packageman.html您可能需要在 JAR 文件的 MANIFEST.MF 中包含包版本信息。您可以使用 MANIFEST.MF 中的以下头部提供此信息: 清单中的头部头部…

Java 中文官方教程 2022 版(二)

原文:docs.oracle.com/javase/tutorial/reallybigindex.html运算符原文:docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html现在你已经学会了如何声明和初始化变量,你可能想知道如何对其进行操作。学习 Java 编程语言的运算符是一个很好的开始。运算符是执行…

狂神说Java Web学习笔记_Session

原理图服务器会给每一个用户(浏览器)创建一个session对象 一个session独占一个浏览器,主要浏览器没有关,这个session就存在 登录之后,整个网站都可以访问 常用场景 保存一个用户的登录信息 在整个网站中经常会使用到的数据 常用的session方法 //得到Session HttpSession s…

CAS 操作原理

CAS(Compare and Swap)是一种原子操作,用于实现乐观锁的一种方式。CAS 操作包括三个参数:内存地址(或变量),期望值和新值。CAS 操作会先比较内存地址处的值和期望值是否相等,如果相等,则将该内存地址的值更新为新值;如果不相等,则不做任何操作。CAS 操作是一种无锁算…

二手交易平台原型图

二手交易平台原型图绘制 墨刀、Axure、Mockplus等原型设计工具优缺点分析Axure优点:强大的编辑功能,便于制作素材库。 快速的复制粘贴,素材库和原型库丰富。 项目共享功能,方便同事间同步工作,保留所有工作历史。 可以生成历史版本的项目文档。缺点:正版的Axure售价高,对…