bzoj 4289 Tax - 最短路
题目传送门
这是一条通往vjudge的神秘通道
这是一条通往bzoj的神秘通道
题目大意
如果一条路径走过的边依次为$e_{1}, e_{2}, \cdots , e_{k}$,那么它的长度为$e_{1} + \max (e_{1}, e_{2}) + \max (e_{2}, e_{3}) + \cdots + \max (e_{k - 1}, e_{k}) + e_{k}$,问点$1$到点$n$的最短路。
显然需要把状态记在最后一条边上。
然后给一个菊花图,这个做法就gg了。
因此考虑一些黑科技。
可以把边看成点,然后考虑如何在辺与边之间快速连边。
对于一个点的出边,可以把它们按照权值排序,大的向比它略小的连一条权值为0的边,小的向比它略大的连一天权值为它们边权之差的边。
然后原图中每条边向它的反向边连一条边权相同的边。
然后再建两个虚点,一个起点,向以1为起点的边连边,边权不变。一个终点,以$n$为终点的边向它连边。
Code
/**
* bzoj
* Problem#4289
* Accepted
* Time: 3200ms
* Memory: 31292k
*/
#include <bits/stdc++.h>
#ifndef WIN32
#define Auto "%lld"
#else
#define Auto "%I64d"
#endif
using namespace std;
typedef bool boolean; #define ll long long typedef class Edge {
public:
int end, next, w; Edge(int end = , int next = , int w = ):end(end), next(next), w(w) { }
}Edge; typedef class MapManager {
public:
int ce;
int *h;
Edge *es; MapManager() { }
MapManager(int n, int m):ce(-) {
h = new int[(n + )];
es = new Edge[(m + )];
memset(h, -, sizeof(int) * (n + ));
} void addEdge(int u, int v, int w) {
es[++ce] = Edge(v, h[u], w);
h[u] = ce;
// cerr << u << "->" << v << " " << w << endl;
} Edge& operator [] (int pos) const {
return es[pos];
}
}MapManager; int n, m;
Edge *es;
vector<int> *dg;
MapManager g; inline void init() {
scanf("%d%d", &n, &m);
es = new Edge[(m + )];
dg = new vector<int>[(n + )];
for (int i = ; i < m; i++) {
scanf("%d%d%d", &es[i].end, &es[i].next, &es[i].w);
dg[es[i].end].push_back(i << );
dg[es[i].next].push_back(i << | );
}
} boolean cmp(const int& a, const int& b) {
return es[a >> ].w < es[b >> ].w;
} int s, t; inline void build() {
g = MapManager((m << ) + , m << );
s = m << , t = m << | ;
for (int i = ; i <= n; i++) {
sort(dg[i].begin(), dg[i].end(), cmp);
for (int j = ; j < (signed) dg[i].size(); j++) {
int u = (j) ? (dg[i][j - ]) : (-), v = dg[i][j];
g.addEdge(v, u, );
g.addEdge(u, v, es[v >> ].w - es[u >> ].w);
}
} for (int i = ; i < (signed) dg[].size(); i++)
g.addEdge(s, dg[][i], es[dg[][i] >> ].w);
for (int i = ; i < (signed) dg[n].size(); i++)
g.addEdge(dg[n][i] ^ , t, es[dg[n][i] >> ].w); for (int i = , w; i < m; i++) {
w = es[i].w;
g.addEdge(i << , i << | , w);
g.addEdge(i << | , i << , w);
}
} typedef class Node {
public:
int p;
ll dis; Node(int p = , ll dis = ):p(p), dis(dis) { } boolean operator < (Node b) const {
return dis > b.dis;
}
}Node; ll *f;
priority_queue<Node> que;
inline ll dijstra() {
f = new ll[(m << ) + ];
memset(f, 0x3f, sizeof(ll) * ((m << ) + ));
que.push(Node(s, f[s] = ));
while (!que.empty()) {
Node e = que.top();
que.pop();
if (e.dis != f[e.p]) continue;
for (int i = g.h[e.p]; ~i; i = g[i].next) {
Node eu (g[i].end, e.dis + g[i].w);
if (eu.dis < f[eu.p]) {
f[eu.p] = eu.dis;
que.push(eu);
}
}
}
return f[t];
} inline void solve() {
printf(Auto"\n", dijstra());
} int main() {
init();
build();
solve();
return ;
}
bzoj 4289 Tax - 最短路的更多相关文章
- bzoj 4289 TAX —— 点边转化
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4289 把边转化成点,同一个原有点相连的边中,边权小的向大的连差值的边,大的向小的连0的边: ...
- 「BZOJ 4289」 PA2012 Tax
「BZOJ 4289」 PA2012 Tax 题目描述 给出一个 \(N\) 个点 \(M\) 条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点 \(1\) 到点 \( ...
- BZOJ 4289: PA2012 Tax 差分建图 最短路
https://www.lydsy.com/JudgeOnline/problem.php?id=4289 https://www.cnblogs.com/clrs97/p/5046933.html ...
- BZOJ 4289: PA2012 Tax(最短路)
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 755 Solved: 240[Submit][Status][Discuss] Descriptio ...
- ●BZOJ 4289 PA2012 Tax
●赘述题目 算了,题目没有重复的必要. 注意理解:对答案造成贡献的是每个点,就是了. 举个栗子: 对于如下数据: 2 1 1 2 1 答案是 2: ●题解 方法:建图(难点)+最短路. 先来几个链接: ...
- BZOJ.4289.PA2012 Tax(思路 Dijkstra)
题目链接 \(Description\) 给出一个N个点M条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点1到点N的最小代价.起点的代价是离开起点的边的边权,终点的代价 ...
- bzoj 4289 PA2012 Tax——构图
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4289 可以把一个点上的边按权值排序,然后边权小的向第一个比它大的连差值的边,边权大的向第一个 ...
- bzoj 4289: PA2012 Tax
Description 给出一个N个点M条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点1到点N的最小代价.起点的代价是离开起点的边的边权,终点的代价是进入终点的边的边 ...
- 【刷题】BZOJ 4289 PA2012 Tax
Description 给出一个N个点M条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点1到点N的最小代价.起点的代价是离开起点的边的边权,终点的代价是进入终点的边的边 ...
随机推荐
- cocos2dx - JS - 碰撞检测
碰撞检测是游戏的一个重要组成部分,我们这里使用一种最简单的方法,就是获取精灵的矩形碰撞框.当然圆形的碰撞检测也比较简单,其他形状就复杂多了.首先是如何获取矩形碰撞框:var hBox=this.her ...
- dotnet 命令
以下用实例串起dotnet常用命令,带你玩转dotnet命令. 1.创建(dotnet new) 首先我们创建一个项目,这里我们创建控制台程序,命令如下图所示. dotnet new dotnet n ...
- Web API 入门 二 媒体类型
还是拿上面 那篇 Web API 入门 一 的那个来讲 在product类中加一个时间属性
- PHP开启mysqli扩展
Call to undefined function mysqli_connect()解决这个问题需要开启mysqli扩展开启mysqli扩展需要这两个步骤缺一不可1.在php.ini中搜索php_m ...
- 关于hibernate一级缓冲和二级缓冲
关于一级缓冲和二级缓冲的内容,在面试的时候被问起来了,回答的不是很满意,所以有专门找了些有关这方面的文章加以理解 出自:http://blog.csdn.net/zdp072/article/deta ...
- linux如何在不重新登录用户的情况下使用户加入的组生效
这个问题在很早之前就遇到了,之前的解决方法是登出用户再登录用户.今天在配置virtualbox的过程中又遇到了同样的问题.于是又进行了一番搜索. 找到了如下答案: https://stackoverf ...
- 深入解析Java反射(1) - 基础
深入解析Java反射(1) - 基础 最近正筹备Samsara框架的开发,而其中的IOC部分非常依靠反射,因此趁这个机会来总结一下关于Java反射的一些知识.本篇为基本篇,基于JDK 1.8. 一.回 ...
- date的用法
date -d "-1 month" "+%T" 当前时间减少一个月 +%T 简便表示时分秒 +%F 简便表示年月日 date +%Y 四位年份 date + ...
- python字典的排序,按key排序和按value排序---sorted()
>>> d{'a': 5, 'c': 3, 'b': 4} >>> d.items()[('a', 5), ('c', 3), ('b', 4)] 字典的元素是成键 ...
- 20165215 2017-2018-2 《Java程序设计》第5周学习总结
20165215 2017-2018-2 <Java程序设计>第5周学习总结 教材学习内容总结 chapter7 Java支持在一个类中声明另外一个类,这样的类称作内部类,而包含内部类的类 ...