题目大意

\(n\)个点,\(m\)次连边

每次连边为\((a\sim b)\leftrightarrow (c\sim d),cost=w\)

即在\((a-b)\)区间内的点向\((c-d)\)区间内的点,两两连一条费用w的双向边

给出\(k\)次机会使一条边费用为\(0\)

求\(1-n\)的最短路

分析

暴力连边\(O(mn^2)\)显然不行

既然是区间连边,是否可以用线段树的方法把区间拆成log个呢

做法

考虑一颗线段树

每次把提取出的\(log\)个区间\(log^2\)连边

然后考虑走到一个线段上

如果线段上每一个点都在当前到达集合,那么可以往下走

由于父亲一定包含当前点,所以可以往上走

但这样分类讨论难以实现

考虑两棵线段树

连边 第一颗树连向第二棵树

第一棵树只能往上走

第二棵树只能往下走

然后第二棵树上的线段连一条边指回第一棵树的对应节点

源点放在第一棵树

汇点放在第二棵树

可以发现,跳完一条边后即到了第二棵树,此时线段上每个点都在可达集合,可以往下走,然后跳回第一棵树,继续走边

是符合要求的

最后考虑回一开始的连边,\(log^2\)的连边跑起dijkstra还是很炸的

但是我们可以强行加一个中间节点,这样边数就变成\(log\)了

连完边跑分层图最短路即可

连边复杂度\(O(m\log n)\)

dijkstra复杂度\(O(m\log^2 n)\)

solution(代码较挫)

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cctype>
#include <cmath>
#include <queue>
using namespace std;
const int M=131077;
const int N=890035;
const int INF=2139062143; inline int ri(){
int x=0;bool f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
for(;isdigit(c);c=getchar()) x=x*10+c-48;
return f?x:-x;
} int tcas,n,m,lim,id,S,T; struct vec{
int g[M<<2],te;
struct edge{
int y,d,nxt;
edge(int _y=0,int _d=0,int _nxt=0){y=_y,d=_d,nxt=_nxt;}
}e[N];
vec(){memset(g,0,sizeof g);te=0;}
inline void push(int x,int y,int d=0){e[++te]=edge(y,d,g[x]);g[x]=te;}
inline int& operator () (int x){return g[x];}
inline edge& operator [] (int x){return e[x];}
}e; struct segment{
int lc[M<<1],rc[M<<1],fa[M<<1],tot,rt;
segment(){
memset(lc,0,sizeof lc);
memset(rc,0,sizeof rc);
tot=0;rt=0;
}
int build(int l,int r){
int x=++tot;
if(l==r) return x;
int mid=l+r>>1;
lc[x]=build(l,mid);
rc[x]=build(mid+1,r);
fa[lc[x]]=x;
fa[rc[x]]=x;
return x;
}
int find(int x,int l,int r,int to){
if(l==r) return x;
int mid=l+r>>1;
if(to<=mid) return find(lc[x],l,mid,to);
return find(rc[x],mid+1,r,to);
}
int find(int x){return find(rt,1,n,x);}
void toid(int x,int l,int r,int tl,int tr,int id,int d){
if(tl<=l&&r<=tr){
e.push(x,id,d);
return;
}
int mid=l+r>>1;
if(tl<=mid) toid(lc[x],l,mid,tl,tr,id,d);
if(mid<tr) toid(rc[x],mid+1,r,tl,tr,id,d);
}
void idto(int x,int l,int r,int tl,int tr,int id,int d){
if(tl<=l&&r<=tr){
e.push(id,x,d);
return;
}
int mid=l+r>>1;
if(tl<=mid) idto(lc[x],l,mid,tl,tr,id,d);
if(mid<tr) idto(rc[x],mid+1,r,tl,tr,id,d);
}
void toid(int l,int r,int id,int d){
toid(rt,1,n,l,r,id,d);
}
void idto(int l,int r,int id,int d){
idto(rt,1,n,l,r,id,d);
}
}L,R; void addedge(int u,int v,int x,int y,int d){
++id;
L.toid(u,v,id,d);
R.idto(x,y,id,0);
} struct node{
int s,x,d;
node(int _s=0,int _x=0,int _d=0){s=_s,x=_x,d=_d;}
bool operator < (const node &y) const{
return d>y.d;
}
};
priority_queue<node>q;
int f[13][M<<2]; void solve(){
memset(f,127,sizeof f);
f[0][S]=0;
q.push(node(0,S,0));
node nw;
int s,x,d,p,y;
while(!q.empty()){
nw=q.top(); q.pop();
s=nw.s; x=nw.x; d=nw.d;
for(p=e(x);p;p=e[p].nxt){
y=e[p].y;
if(d+e[p].d<f[s][y]){
f[s][y]=d+e[p].d;
q.push(node(s,y,f[s][y]));
}
if(s<lim&&d<f[s+1][y]){
f[s+1][y]=d;
q.push(node(s+1,y,f[s+1][y]));
}
}
} int i,ans=INF;
for(i=0;i<=lim;i++) ans=min(ans,f[i][T]);
if(ans==INF) puts("Yww is our red sun!");
else printf("%d\n",ans);
} int main(){ int i,u,v,x,y,d; tcas=ri();
n=ri(),m=ri(),lim=ri(); L.tot=0; L.build(1,n); L.rt=1;
R.tot=L.tot; R.build(1,n); R.rt=L.tot+1;
S=L.find(1); T=R.find(n); id=R.tot;
for(i=L.rt+1;i<=L.tot;i++) e.push(i,L.fa[i]);
for(i=R.rt;i<=R.tot;i++) e.push(i,i-L.tot);
for(i=R.rt+1;i<=R.tot;i++) e.push(R.fa[i],i); while(m--){
u=ri(),v=ri(),x=ri(),y=ri(),d=ri();
addedge(u,v,x,y,d);
addedge(x,y,u,v,d);
} solve(); return 0;
}

hdu 5669 Road的更多相关文章

  1. HDU 5669 Road(线段树建树)(分层图最短路)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5669 [分析]线段树建树+分层图最短路 #include <cstdio> #includ ...

  2. hdu 5861 Road 两棵线段树

    传送门:hdu 5861 Road 题意: 水平线上n个村子间有 n-1 条路. 每条路开放一天的价格为 Wi 有 m 天的操作,每天需要用到村子 Ai~Bi 间的道路 每条路只能开放或关闭一次. ( ...

  3. HDU 5861 Road (线段树)

    Road 题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=5861 Description There are n villages alo ...

  4. HDU 5861 Road 线段树区间更新单点查询

    题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=5861 Road Time Limit: 12000/6000 MS (Java/Othe ...

  5. HDU 5861 Road(线段树 区间修改 单点查询)

    Road Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submi ...

  6. HDU 3917 Road constructions(最小割---最大权闭合)

    题目地址:HDU 3917 这题简直神题意... 题目本身就非常难看懂不说..即使看懂了.也对这题意的逻辑感到无语...无论了.. 就依照那题意上说的做吧... 题意:给你n个城市,m个公司.若干条可 ...

  7. 2016 Multi-University Training Contest 10 [HDU 5861] Road (线段树:区间覆盖+单点最大小)

    HDU 5861 题意 在n个村庄之间存在n-1段路,令某段路开放一天需要交纳wi的费用,但是每段路只能开放一次,一旦关闭将不再开放.现在给你接下来m天内的计划,在第i天,需要对村庄ai到村庄bi的道 ...

  8. HDU 5669 线段树优化建图+分层图最短路

    用线段树维护建图,即把用线段树把每个区间都标号了,Tree1中子节点有到达父节点的单向边,Tree2中父节点有到达子节点的单向边. 每次将源插入Tree1,汇插入Tree2,中间用临时节点相连.那么T ...

  9. hdu 3917 Road constructions 最大权闭合子图

    样例说明: n(城市数目)   m(工程队数目) 每个工程队上交的税收 val[i] k(k个工程) xi   yi  ci  costi , 工程队ci承包由xi到yi,政府的补贴为costi 注意 ...

随机推荐

  1. 01_14_Struts2_结果类型_result_type

    01_14_Struts2_结果类型_result_type 1. result类型 result类型 说明 dispatcher 默认服务端转发jsp chain 服务端action转发 redir ...

  2. 【转】【win网络编程】socket中的recv阻塞和select的用法

    在编写ftp客户端程序时,在联通后使用recv函数进行接收欢迎信息时,需要申请内存进行接收数据保存,一次读取成功,但是由于一个随机的ftp服务端在说,欢迎信息的大小是不知道的,所以在尝试使用死循环,在 ...

  3. 5-3 time模块

    1.取当前时间戳和当前格式化时间 import time1 # 以时间戳的形式打印当前时间 1543849862 print(int(time.time()))#时间戳 # 取当前格式化好的时间 20 ...

  4. JavaScriptDate(日期)

    如何使用Date()方法获取当日的日期. getFullYear(): 使用getFullYear()获取年份. getTime(): getTime()返回1970年1月1日至今的毫秒数. setF ...

  5. vmware 开机自动启动

    vmware开机自动启动, 可以使用vmrun命令. 1. 首先在“我的电脑”-“属性”-“高级”-“环境变量”-“PATH”中添加vmware路径,如:C:\Program Files (x86)\ ...

  6. MongDB之各种修改操作

    接口IMongDaoUpdate: package com.net.test.mongdb.dao; import com.net.test.mongdb.entity.User; public in ...

  7. Missian指南三:创建一个Missian服务器(使用spring)

    在使用Missian时,spring是可选的,但是作者本人强烈推荐和Spring配合使用.Spring是一个伟大的项目,并且它不会对程序在运行时的效率带来任何损耗. Missian在服务器端依赖与Mi ...

  8. 华东交通大学2018年ACM“双基”程序设计竞赛 D

      摸鱼之王MIKU酱想去埃及玩,需要一个人陪同.小新和小磊都想陪MIKU酱一起去,但名额只有一个.所以小磊和小新决定用一个小游戏来决定谁和MIKU酱出去玩.    游戏的道具是21张塔罗牌,塔罗牌分 ...

  9. python数据模型(特殊方法)

    python中的全部特殊方法 本部分内容可以参考官方网址 python中一共有83个特殊方法,其中47个用于算术运算.位运算和比较操作.我根据<流畅的python>中的整理,摘录如下两个表 ...

  10. Redis实现之复制(二)

    PSYNC命令的实现 在Redis实现之复制(一)这一章中,我们介绍了PSYNC命令和它的工作机制,但一直没有说明PSYNC命令的参数以及返回值.现在,我们了解了运行ID.复制偏移量.复制积压缓冲区以 ...