用线段树维护建图,即把用线段树把每个区间都标号了,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. 关于ifram之间的相互调用

    window.iframeId.btnClose.click(); 父调子 window.parent.FatherFunciton(); 子调父

  2. Swashbuckle for asp.net core 配置说明

    0x00 安装 Swashbuckle 6.0 打开程序包管理器控制台,输入: Install-Package Swashbuckle -Pre 0x01 配置 Startup.cs public v ...

  3. python之redis

    Redis简单介绍 如果简单地比较Redis与Memcached的区别,大多数都会得到以下观点:1 Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构 ...

  4. 2016年12月25日 星期日 --出埃及记 Exodus 21:20

    2016年12月25日 星期日 --出埃及记 Exodus 21:20 "If a man beats his male or female slave with a rod and the ...

  5. selenium杀掉浏览器进程方法

    * 杀掉浏览器进程      */     public static void operateWindowsProcess(){         WindowsUtils.tryToKillByNa ...

  6. Python多进程编程

    转自:Python多进程编程 阅读目录 1. Process 2. Lock 3. Semaphore 4. Event 5. Queue 6. Pipe 7. Pool 序. multiproces ...

  7. [issue] dyld`dyld_fatal_error: -> 0x120015088 <+0>: brk #0x3

    iOS "dyld`dyld_fatal_error: -> 0x12000d088 <+0>: brk #0x3"错误 根据上面的博客里的方法二 尝试解决方法二 ...

  8. C#读取XML文件中有乱码的处理办法

    1.以文本的方式读取出xml内容 2.如果xml加载文本失败,替换掉乱码的内容 private static void loadxml(XmlDocument doc, string str) { t ...

  9. JAVA 列表排序

    以前都通过Comparator进行排序,今天看到个例子,通过apache-common工具包进行排序,实现例子参考下面界面 http://blog.csdn.net/lizeyang/article/ ...

  10. 当一个类、一个实例域、方法被定义为private、public 时意味着什么

    1.设计private public的原因 2.当一个类.一个实例域.方法被定义为private.public 时意味着什么