B - Legacy

CodeForces - 787D

这个题目开始看过去还是很简单的,就是一个最短路,但是这个最短路的建图没有那么简单,因为直接的普通建图边太多了,肯定会超时的,所以要用线段树来优化建图。

这个题目我一开始也没想到,不知道怎么用线段树优化,然后看了一下题解,豁然开朗。

首先建两棵线段树,有点类似拆点,然后其中一颗从下往上建图A,一颗从上往下建图B。

从上往下建图的每一个叶子节点连着从上往下建图的每一个叶子节点。 权值都是0

p==1 那就直接是B 的叶子节点连着A 的叶子节点,权值为w

p==2 那就是A的叶子节点v 连着B的这个区间的节点

p==3 那就是A 的区间节点连着B的叶子节点v

起点在A这颗树的地球位置的根节点。

建完图之后就是跑一个最短路。

这个是大概思路,但是怎么写呢,

首先肯定是建树,建树的过程中建图,而且还要记录每一个节点的编号,并且记录每一个叶子节点的编号。

然后就是根据要求建图如果是区间就要进行查找这个区间节点就可以了。

接下来就是考验码力的时候了。

这个题目想清楚之后就不是很难写了,只是这个空间要注意,因为这个wa了三发。

这个方法要学习学习。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
#include <map>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 2e5 + ;
int numa[maxn * ], numb[maxn * ], lefta[maxn * ], leftb[maxn * ];
ll d[maxn*], tot;
int n, m;
bool vis[maxn*];
struct edge {
int from, to, dist;
edge(int from=, int to=, int dist=) :from(from), to(to), dist(dist) {}
};
struct heapnode {
int u;
ll d;
heapnode(ll d=, int u=) : d(d), u(u) {}
bool operator<(const heapnode &a) const {
return a.d < d;
}
}; vector<edge> vec;
vector<int> g[maxn*]; void add(int u,int v,int w)
{
vec.push_back(edge(u, v, w));
int m = vec.size();
g[u].push_back(m - );
// printf("u=%d v=%d w=%d\n", u, v, w);
} void dijkstra(int s) {
priority_queue<heapnode>que;
for (int i = ; i <= tot; i++) d[i] = inf64;
d[s] = ;
memset(vis, , sizeof(vis));
que.push(heapnode(, s));
while (!que.empty()) {
heapnode x = que.top(); que.pop();
int u = x.u;
if (vis[u]) continue;
vis[u] = ;
for (int i = ; i < g[u].size(); i++) {
edge &e = vec[g[u][i]];
// printf("u=%d e.to=%d e.dist=%d\n", u, e.to, e.dist);
// printf("d[%d]=%lld d[%d]=%lld\n", u, d[u], e.to, d[e.to]);
if (d[e.to] > d[u] + e.dist) {
// printf("ww\n");
d[e.to] = d[u] + e.dist;
que.push(heapnode(d[e.to], e.to));
}
}
}
for(int i=;i<=n;i++)
{
if (d[lefta[i]] >= inf64) printf("-1 ");
else printf("%lld ", d[lefta[i]]);
}
} void builda(int id,int l,int r)
{
numa[id] = ++tot;
int mid = (l + r) >> ;
if(l==r)
{
lefta[l] = tot;
return;
}
builda(id << , l, mid);
builda(id << | , mid + , r);
add(numa[id << ], numa[id], );
add(numa[id << | ], numa[id], );
} void buildb(int id,int l,int r)
{
numb[id] = ++tot;
int mid = (l + r) >> ;
if(l==r)
{
leftb[l] = tot;
return;
}
buildb(id << , l, mid);
buildb(id << | , mid + , r);
add(numb[id], numb[id << ], );
add(numb[id], numb[id << | ], );
} void build3(int n)
{
for (int i = ; i <= n; i++) add(leftb[i], lefta[i], );
} void updatea(int id,int l,int r,int x,int y,int b,int w)
{
if (x <= l && y >= r) {
add(numa[id], b, w);
return;
}
int mid = (l + r) >> ;
if (x <= mid) updatea(id << , l, mid, x, y, b, w);
if (y > mid) updatea(id << | , mid + , r, x, y, b, w);
} void updateb(int id,int l,int r,int x,int y,int a,int w)
{
if(x<=l&&y>=r)
{
add(a, numb[id], w);
return;
}
int mid = (l + r) >> ;
if (x <= mid) updateb(id << , l, mid, x, y, a, w);
if (y > mid) updateb(id << | , mid + , r, x, y, a, w);
} int main()
{
int s;
tot = ;
scanf("%d%d%d", &n, &m, &s);
builda(, , n), buildb(, , n), build3(n);
while(m--)
{
int opt, u, v, l, r, w;
scanf("%d", &opt);
if (opt == ) {
scanf("%d%d%d", &u, &v, &w);
add(lefta[u], leftb[v], w);
}
if(opt==)
{
scanf("%d%d%d%d", &u, &l, &r, &w);
updateb(, , n, l, r, lefta[u], w);
}
if(opt==)
{
scanf("%d%d%d%d", &u, &l, &r, &w);
updatea(, , n, l, r, leftb[u], w);
}
}
dijkstra(lefta[s]);
return ;
}

线段树+最短路

B - Legacy CodeForces - 787D 线段树优化建图+dij最短路 基本套路的更多相关文章

  1. G. 神圣的 F2 连接着我们 线段树优化建图+最短路

    这个题目和之前写的一个线段树优化建图是一样的. B - Legacy CodeForces - 787D 线段树优化建图+dij最短路 基本套路 之前这个题目可以相当于一个模板,直接套用就可以了. 不 ...

  2. CF786B Legacy 线段树优化建图 + spfa

    CodeForces 786B Rick和他的同事们做出了一种新的带放射性的婴儿食品(???根据图片和原文的确如此...),与此同时很多坏人正追赶着他们.因此Rick想在坏人们捉到他之前把他的遗产留给 ...

  3. [Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路)

    [Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路) 题面 有n个空心物品,每个物品有外部体积\(out_i\)和内部体积\(in_i\),如果\(in_i& ...

  4. BZOJ5017 [SNOI2017]炸弹 - 线段树优化建图+Tarjan

    Solution 一个点向一个区间内的所有点连边, 可以用线段树优化建图来优化 : 前置技能传送门 然后就得到一个有向图, 一个联通块内的炸弹可以互相引爆, 所以进行缩点变成$DAG$ 然后拓扑排序. ...

  5. 【BZOJ3681】Arietta 树链剖分+可持久化线段树优化建图+网络流

    [BZOJ3681]Arietta Description Arietta 的命运与她的妹妹不同,在她的妹妹已经走进学院的时候,她仍然留在山村中.但是她从未停止过和恋人 Velding 的书信往来.一 ...

  6. 【ARC069F】Flags 2-sat+线段树优化建图+二分

    Description ​ 数轴上有 n 个旗子,第 ii 个可以插在坐标 xi或者 yi,最大化两两旗子之间的最小距离. Input ​ 第一行一个整数 N. ​ 接下来 N 行每行两个整数 xi, ...

  7. 【bzoj5017】[Snoi2017]炸弹 线段树优化建图+Tarjan+拓扑排序

    题目描述 在一条直线上有 N 个炸弹,每个炸弹的坐标是 Xi,爆炸半径是 Ri,当一个炸弹爆炸时,如果另一个炸弹所在位置 Xj 满足:  Xi−Ri≤Xj≤Xi+Ri,那么,该炸弹也会被引爆.  现在 ...

  8. 【bzoj4699】树上的最短路(树剖+线段树优化建图)

    题意 给你一棵 $n$ 个点 $n-1$ 条边的树,每条边有一个通过时间.此外有 $m$ 个传送条件 $(x_1,y_1,x_2,y_2,c)$,表示从 $x_1$ 到 $x_2$ 的简单路径上的点可 ...

  9. 【BZOJ4276】[ONTAK2015]Bajtman i Okrągły Robin 线段树优化建图+费用流

    [BZOJ4276][ONTAK2015]Bajtman i Okrągły Robin Description 有n个强盗,其中第i个强盗会在[a[i],a[i]+1],[a[i]+1,a[i]+2 ...

随机推荐

  1. cmake添加版本号

    vVersion.cmake文件内容如下: #vversion.cmake #vDateTime string(TIMESTAMP vDateTime "%Y%m%d-%H%M%S" ...

  2. mysql 向上取整

    SELECT CEILING(10.0)    --->10 SELECT CEILING(10.1)    --->11

  3. xxx 表 is marked as crashed and last (automatic?) repair 解决办法

    如上图出现 xxx 表 is marked xxxx   的问题 运维那说是因为数据库非正常停掉 时 刚好有数据正在写入 数据库 导致的问题,这个没多大影响,需要 执行命令修复数据库,至于命令是什么? ...

  4. search(5)- elastic4s-构建索引

    按照计划,这篇开始尝试用elastic4s来做一系列索引管理和搜索操作示范.前面提过,elastic4s的主要功能之一是通过组合Dsl语句形成json请求.那么我们先试试组合一些Dsl语句,再想办法产 ...

  5. 拍照购物APP之可行性分析

    你一定有过这样的生活经历:走在路上发现一个陌生人的穿着非常符合自己的穿衣品味,想要购买一件同样款式的衣服却找不到购买地址,偷偷拍了张照片也只能留作纪念.此时,在手机上安装一款通过图片进行购物搜索的AP ...

  6. Rescue BFS+优先队列 杭电1242

    思路 : 优先队列 每次都取最小的时间,遇到了终点直接就输出 #include<iostream> #include<queue> #include<cstring> ...

  7. weblogic漏洞(一)----CVE-2017-10271

    WebLogic XMLDecoder反序列化漏洞(CVE-2017-10271) 0x01 漏洞原因: Weblogic的WLS Security组件对外提供webservice服务,其中使用了XM ...

  8. (转载)基于BIGINT溢出错误的SQL注入

    我对于通过MySQL错误提取数据的新技术非常感兴趣,而本文中要介绍的就是这样一种技术.当我考察MySQL的整数处理方式的时候,突然对如何使其发生溢出产生了浓厚的兴趣.下面,我们来看看MySQL是如何存 ...

  9. [整理]svn常见问题汇总

    1.’.’ is not a working copy.Can’t open file‘.svn/entries’: 系统找不到指定的路径.解答:原因是输入的访问路径不正确,如svn://192.16 ...

  10. foreach 里少用&$v

    foreach ( $prize_list as $k => $v ) { $prize_list[$k]['prize_view'] = DB::name('dati_prize_catego ...