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. 对象中属性 加锁 用:volatile 关键词修饰 而 不用 synchronized 加锁

    一个对象中有一个状态 属性,现在业务需求 存在多线程来修改 和 拿去 这个状态 的值,这种情况如果加锁怎么加? 一种是 在 set 和get 这个状态的 方法那加 synchronized . 还有一 ...

  2. HTTP 405 的错误提示:消息 JSP 只允许 GET、POST 或 HEAD。Jasper 还允许 OPTIONS 的解决方法

    如果项目是运行在 Tomcat 8 及以上,会发现发出的 PUT 请求和 DELETE 请求可以被控制其接收到,但是返回页面时(forward)会报HTTP 405 的错误提示:"消息 JS ...

  3. 009-数组-C语言笔记

    009-数组-C语言笔记 学习目标 1.[掌握]数组的声明 2.[掌握]数组元素的赋值和调用 3.[掌握]数组的初始化 4.[掌握]数组的遍历 5.[掌握]数组在内存中的存储 6.[掌握]数组长度计算 ...

  4. Linux下搭建接口自动化测试平台

    前言 我们今天来学习一下在Linux下如何搭建基于HttpRunner开发的接口自动化测试平台吧! 需要在Linux上提前准备的环境(下面是本人搭建时的环境): 1,Python 3.6.8 (可参考 ...

  5. c语言中的引用使用

    最近在写一个图像处理的程序时候,遇到一些传参的问题,最后发现引用的效率高一些,在此提醒各位道友,多多关注引用的应用及使用. 1.在引用的使用中,单纯给某个变量取个别名是毫无意义的,不要为了耍酷而乱用, ...

  6. 实验一 熟悉IDLE和在线编程平台

    实验目的 1.掌握python IDLE集成开发环境的安装与使用 2.熟悉在线编程平台 3.掌握基本的python程序编写.编译与运行程序的方法 实验内容 1.按照实验指导安装IDLE,尝试交互式运行 ...

  7. 深入浅出node.js游戏服务器开发1——基础架构与框架介绍

    2013年04月19日 14:09:37 MJiao 阅读数:4614   深入浅出node.js游戏服务器开发1——基础架构与框架介绍   游戏服务器概述 没开发过游戏的人会觉得游戏服务器是很神秘的 ...

  8. 深度学习之文本分类模型-前馈神经网络(Feed-Forward Neural Networks)

    目录 DAN(Deep Average Network) Fasttext fasttext文本分类 fasttext的n-gram模型 Doc2vec DAN(Deep Average Networ ...

  9. 人体和电脑的关系——鸟哥的LINUX私房菜基础学习篇读书笔记

    CUP=脑袋: 每个人会做的事情都不一样(指令集的差异),但主要都是通过脑袋来判断与控制身体各部分的行动 内存=脑袋中存放正在思考的数据区块: 在实际活动过程中,我们的脑袋需要有外界刺激的数据(例如光 ...

  10. Java 动态编译--DynamicCompiler

    java 动态编译自己写过程的机会比较少,记录一下: package com.xzlf.dynamicCompile; import java.io.IOException; import java. ...