用线段树维护建图,即把用线段树把每个区间都标号了,Tree1中子节点有到达父节点的单向边,Tree2中父节点有到达子节点的单向边.

每次将源插入Tree1,汇插入Tree2,中间用临时节点相连。那么Tree1中的所用子节点都可以到达,Tree2中的所用子节点。 

感觉很有道理啊,以前从来没用用线段树这样维护过建图。分层图最短路没有像BZOJ2763可以直接向先一层连边,因为边已经很多了。

 #include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#define pa pair<int,int>
#define pa3 pair<int,pa>
#define mp make_pair
#define fi first
#define se second
#define pb push_back
using namespace std;
const int Maxn=;
const int Maxk=;
struct Edge{int to,next,w;}edge[Maxn<<];
vector<int> P1,P2;
priority_queue<pa3,vector<pa3>,greater<pa3> > Q;
int n,m,Id1[Maxn],Id2[Maxn],head[Maxn],dis[Maxn][Maxk],cnt,Block;
int Kase,v,k;
inline void Add(int u,int v,int w)
{edge[cnt].to=v;edge[cnt].next=head[u];edge[cnt].w=w;head[u]=cnt++;}
inline int Max(int x,int y) {return x>y?x:y;}
inline void Get_Int(int &x)
{
x=; char ch=getchar(); int f=;
while (ch<'' || ch>'') {if (ch=='-') f=-; ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();} x*=f;
}
inline void Put_Int(int x)
{
char ch[]; int top=;
if (x==) ch[++top]='';
while (x) ch[++top]=x%+'',x/=;
while (top) putchar(ch[top--]); putchar('\n');
}
void Build1(int o,int l,int r)
{
Block=Max(Block,o);
if (l==r) {Id1[l]=o; return;}
int mid=(l+r)>>;
Build1(o<<,l,mid),Build1(o<<|,mid+,r);
Add(o<<,o,),Add(o<<|,o,);
}
void Build2(int o,int l,int r)
{
if (l==r) {Id2[l]=Block+o; Add(Id2[l],Id1[l],);return;}
int mid=(l+r)>>;
Build2(o<<,l,mid),Build2(o<<|,mid+,r);
Add(Block+o,Block+(o<<),),Add(Block+o,Block+(o<<|),);
}
void Modify1(int o,int l,int r,int p,int q)
{
if (l==p && r==q) {P1.pb(o); return;}
int mid=(l+r)>>;
if (q<=mid) Modify1(o<<,l,mid,p,q);
if (p>=mid+) Modify1(o<<|,mid+,r,p,q);
if (p<=mid && q>=mid+)
Modify1(o<<,l,mid,p,mid),Modify1(o<<|,mid+,r,mid+,q);
}
void Modify2(int o,int l,int r,int p,int q)
{
if (l==p && r==q) {P2.pb(o+Block); return;}
int mid=(l+r)>>;
if (q<=mid) Modify2(o<<,l,mid,p,q);
if (p>=mid+) Modify2(o<<|,mid+,r,p,q);
if (p<=mid && q>=mid+)
Modify2(o<<,l,mid,p,mid),Modify2(o<<|,mid+,r,mid+,q);
} void Dij()
{
memset(dis,0x7f,sizeof(dis));
Q.push(mp(,mp(Id1[],))); dis[Id1[]][]=;
while (!Q.empty())
{
int u=Q.top().se.fi,v=Q.top().se.se; Q.pop();
for (int i=head[u];i!=-;i=edge[i].next)
{
if (dis[edge[i].to][v]>dis[u][v]+edge[i].w)
{
dis[edge[i].to][v]=dis[u][v]+edge[i].w;
Q.push(mp(dis[edge[i].to][v],mp(edge[i].to,v)));
}
if (v<k)
{
if (dis[edge[i].to][v+]>dis[u][v])
{
dis[edge[i].to][v+]=dis[u][v];
Q.push(mp(dis[edge[i].to][v+],mp(edge[i].to,v+)));
}
}
}
}
} int main()
{
Get_Int(Kase);
for (int kase=;kase<=Kase;kase++)
{
Get_Int(n),Get_Int(m),Get_Int(k);
memset(head,-,sizeof(head)); Block=;
Build1(,,n); Block++; Build2(,,n);
int tot=(Block<<)+,a,b,c,d,w;
for (int i=;i<=m;i++)
{
Get_Int(a),Get_Int(b),Get_Int(c),Get_Int(d),Get_Int(w);
P1.clear(),P2.clear();
Modify1(,,n,a,b);
Modify2(,,n,c,d);
tot++;
for (int j=;j<P1.size();j++) Add(P1[j],tot,w);
for (int j=;j<P2.size();j++) Add(tot,P2[j],); P1.clear(),P2.clear();
Modify1(,,n,c,d);
Modify2(,,n,a,b);
tot++;
for (int j=;j<P1.size();j++) Add(P1[j],tot,w);
for (int j=;j<P2.size();j++) Add(tot,P2[j],);
}
}
Dij();
if (dis[Id2[n]][k]==0x7fffffff) puts("CreationAugust is a sb!"); else
Put_Int(dis[Id2[n]][k]);
return ;
}

把标答代码改成Dij系列..

HDU 5669 线段树优化建图+分层图最短路的更多相关文章

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

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

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

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

  3. 洛谷P3588 [POI2015]PUS(线段树优化建图)

    题面 传送门 题解 先考虑暴力怎么做,我们把所有\(r-l+1-k\)中的点向\(x\)连有向边,表示\(x\)必须比它们大,那么如果这张图有环显然就无解了,否则的话我们跑一个多源最短路,每个点的\( ...

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

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

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

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

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

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

  7. 【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 ...

  8. 【bzoj3073】[Pa2011]Journeys 线段树优化建图+堆优化Dijkstra

    题目描述 Seter建造了一个很大的星球,他准备建造N个国家和无数双向道路.N个国家很快建造好了,用1..N编号,但是他发现道路实在太多了,他要一条条建简直是不可能的!于是他以如下方式建造道路:(a, ...

  9. 【bzoj4383】[POI2015]Pustynia 线段树优化建图+差分约束系统+拓扑排序

    题目描述 给定一个长度为n的正整数序列a,每个数都在1到10^9范围内,告诉你其中s个数,并给出m条信息,每条信息包含三个数l,r,k以及接下来k个正整数,表示a[l],a[l+1],...,a[r- ...

随机推荐

  1. [课程设计]Scrum 3.1 多鱼点餐系统开发进度(第三阶段项目构思与任务规划)

    Scrum 3.1 多鱼点餐系统开发进度(第三阶段项目构思与任务规划) 1.团队名称:重案组 2.团队目标:长期经营,积累客户充分准备,伺机而行 3.团队口号:矢志不渝,追求完美 4.团队选题:餐厅到 ...

  2. 模板引擎:ArtTemplate 使用入门和简单的使用

    下载地址:https://github.com/aui/artTemplate 快速上手请参考:https://github.com/aui/artTemplate 通过阅读artTemplate原文 ...

  3. JSON下

    JSON下:目录一:把 JSON 文本转换为 JavaScript 对象二:JSON 实例 - 来自字符串的对象 一.把 JSON 文本转换为 JavaScript 对象JSON 最常见的用法之一,是 ...

  4. python 学习笔记十二 html基础(进阶篇)

    HTML 超级文本标记语言是标准通用标记语言下的一个应用,也是一种规范,一种标准,它通过标记符号来标记要显示的网页中的各个部分.网页文件本身 是一种文本文件,通过在文本文件中添加标记符, 可以告诉浏览 ...

  5. web前段 弹出小例子

    <html> <head> <meta charset="utf-8"> <meta name="viewport" ...

  6. Python3基础 int(input())输入数字并产生一个int类型变量

    镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...

  7. Winform开发框架之介绍

    winform开发框架,尽量减少程序员在界面中的代码量和工作量,Model自动生成,界面以及控件自动生成,简单的逻辑自动生成.自动生成的界面已经实现简单逻辑增删改查功能. 其他开发框架都已经或多火烧实 ...

  8. iOS应用性能调优建议

    本文来自iOS Tutorial Team 的 Marcelo Fabri,他是Movile的一名 iOS 程序员.这是他的个人网站:http://www.marcelofabri.com/,你还可以 ...

  9. C#中的多线程 - 基础知识

    原文:http://www.albahari.com/threading/ 文章来源:http://blog.gkarch.com/threading/part1.html 1简介及概念 C# 支持通 ...

  10. ITerm2下使用ssh访问Linux

    通常情况下,iTerm2访问远程Linux使用ssh,与Termial基本一样,方法如下: ssh <用户名>@<ip> 然后输入访问的密码即可.当然还有的时候需要指定访问端口 ...