用线段树维护建图,即把用线段树把每个区间都标号了,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. pickle与shelve

    pickle Example 写入文件 import pickle integers = [1, 2, 3, 4, 5] with open('pickle-example.p', 'wb') as ...

  2. Hibernate配置文件

    <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hi ...

  3. PHP匿名函数的使用

    $dealer = array(); array_walk($dealer_id_arr,function($value) use(&$dealer) { $dealer[] = get_co ...

  4. Linux用户与“最小权限”原则

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 作为一个Linux用户来说,我们并不需要特别关心下面的机制.但是,当我们去编写一个 ...

  5. 扩展XAF模型信息实现自定义功能

    如何隐藏 web listview 的 编辑控制列如下图: 这列怎么让它隐藏? 感谢[少侠]XAF_杨东 提供解答!感谢XAF_小学生整理.   A: 注册自定义接口IModelListViewExt ...

  6. JQuery对表格进行排序

    添加相关jar <script type="text/javascript" src="jquery-1.1.3.pack.js"></scr ...

  7. MFC编程入门之十(对话框:设置对话框控件的Tab顺序)

    前面几节为大家演示了加法计算器程序完整的编写过程,本节主要讲对话框上控件的Tab顺序如何调整. 上一讲为"计算"按钮添加了消息处理函数后,加法计算器已经能够进行浮点数的加法运算.但 ...

  8. [Java基础]循环结构3

    [Java基础]循环结构3 break 与 continue 中断循环... /** 文件路径:G:\JavaByHands\循环语句\ 文件名称:BreakTest.java 编写时间:2016/6 ...

  9. 转!mysql 查询 distinct多个字段 注意!!

    前几天做项目时,mysql写了个sql, distinct  id,col1,col2,...  结果出来了多条同个ID的记录,百度了下..... 下面先来看看例子: table  id name  ...

  10. SSH项目Class类的注解与属性的注解

    经过一段日子对SSH的学习,为了有利于随时能熟练的把一个SSH的项目快速的搭建起来,并且在报错的时候,将报错信息和解决 方案记录下来,每天一次的代码练习已成为家常便饭 所以,在反复练习的时候,发现Sp ...