题面

Description

给定一张 N 个点的图, 点的标号为 1 到 n . 我们进行 M 次连边, 每次连边可以描述为 a b c d w :

for i = a to b do
for j = c to d do
Add_Edge(i,j,w)

Add_Edge(i,j,w) 表示从点 i 向点 j 连一条费用为 w 的双向边.

求点 1 到点 n 的最小花费.

为了降低难度, 我们有 K 次机会可以消除某条边的花费.

Input

第一行一个数 T , 表示测试数据组数. 出于某种原因, T=1 .

第二行三个数 N,M,K .

接下来 M 行, 每行 5 个数 a,b,c,d,w , 意义如 题目描述 所示.

Output

一行一个数, 为最小的花费.

如果点 1 与点 n 不连通, 输出 "Yww is our red sun!" .

Sample Input

1
5 3 0
1 2 4 5 42
5 5 4 4 468
1 1 3 3 335

Sample Output

42

HINT

\(T=1\), \(1≤N≤5×10^4\), \(1≤M≤10^4\), \(0≤K≤10\), \(1≤w≤10^3\)

题解

考虑到题目要求的是一个区间的点和另一个区间的点连边, 我们可以建立两棵线段树来维护这些区间.

我们建立的两棵线段树, 一棵叫作源线段树, 一棵叫作汇线段树, 每次连边的时候(这里指的是连单向边的步骤, 双向边要逆过来再做一次), 新建一个节点, 将一棵线段树的对应区间的节点向这个点连边, 再将这个点和另一颗线段树上对应的点连边.

大致思路就是这样. 具体的还有一些连边自行脑补.

考虑如何跑最短路.

由于这里有\(K\)条边的权值可以不用算, 因此我们要跑的是分层图最短路, 意思是在跑Dijkstra的时候不单要记录距离, 还要记录用了多少张免费票.

#include <cstdio>
#include <cstring>
#include <cctype>
#include <vector>
#include <queue> namespace Zeonfai
{
inline int getInt()
{
int a = 0, sgn = 1;
char c;
while(! isdigit(c = getchar()))
if(c == '-')
sgn *= -1;
while(isdigit(c))
a = a * 10 + c - '0', c = getchar();
return a * sgn;
}
inline void print(int a)
{
if(! a)
return;
print(a / 10);
putchar('0' + a % 10);
}
inline void println(int a)
{
if(a < 0)
putchar('-'), a *= -1;
if(a == 0)
putchar('0');
print(a);
putchar('\n');
}
}
const int N = (int)5e4, INF = (int)1e9, K = 10;
struct graph
{
struct node;
struct edge
{
node *v;
int w;
inline edge(node *_v, int _w)
{
v = _v, w = _w;
}
};
struct node
{
int ed, dis[K + 1];
std::vector<edge> edg;
inline node()
{
ed = 0;
for(int i = 0; i <= K; ++ i)
dis[i] = INF;
edg.clear();
}
}nd[N << 2][2], *S;
inline void addEdge(node *u, node *v, int w)
{
u->edg.push_back(edge(v, w));
}
void build(int u, int L, int R, int bnd)
{
addEdge(&nd[u][1], &nd[u][0], 0);
if(L == R)
{
if(R == bnd)
nd[u][0].ed = nd[u][1].ed = 1;
if(L == 1)
S = &nd[u][0];
return;
}
int mid = L + R >> 1;
addEdge(&nd[u << 1][0], &nd[u][0], 0), addEdge(&nd[u][1], &nd[u << 1][1], 0);
build(u << 1, L, mid, bnd);
addEdge(&nd[u << 1 | 1][0], &nd[u][0], 0), addEdge(&nd[u][1], &nd[u << 1 | 1][1], 0);
build(u << 1 | 1, mid + 1, R, bnd);
}
void build(int n)
{
build(1, 1, n, n);
}
std::vector<node*> bck[2];
void get(int u, int curL, int curR, int L, int R, int flg)
{
if(curL >= L && curR <= R)
{
bck[flg].push_back(&nd[u][flg]);
return;
}
int mid = curL + curR >> 1;
if(L <= mid)
get(u << 1, curL, mid, L, R, flg);
if(R > mid)
get(u << 1 | 1, mid + 1, curR, L, R, flg);
}
void link(int a, int b, int c, int d, int w, int n)
{
bck[0].clear(), bck[1].clear();
get(1, 1, n, a, b, 0), get(1, 1, n, c, d, 1);
node *u = new node;
for(auto p : bck[0])
addEdge(p, u, w);
for(auto p : bck[1])
addEdge(u, p, 0);
u = new node;
for(auto p : bck[0])
addEdge(u, p, 0);
for(auto p : bck[1])
addEdge(p, u, w);
}
struct state
{
node *u;
int k, dis;
inline state(node *_u, int _k, int _dis)
{
u = _u, k = _k, dis = _dis;
}
inline int friend operator <(state a, state b)
{
return a.dis > b.dis;
}
};
inline int dijkstra(int k)
{
std::priority_queue<state> hp;
S->dis[0] = 0;
hp.push(state(S, 0, 0));
for(; ! hp.empty(); hp.pop())
{
state stt = hp.top();
node *u = stt.u;
if(u->ed)
return stt.dis;
for(auto p : u->edg)
{
if(stt.dis + p.w < p.v->dis[stt.k])
p.v->dis[stt.k] = stt.dis + p.w, hp.push(state(p.v, stt.k, p.v->dis[stt.k]));
if(stt.k < k && u->dis[stt.k] < p.v->dis[stt.k + 1])
p.v->dis[stt.k + 1] = stt.dis, hp.push(state(p.v, stt.k + 1, p.v->dis[stt.k + 1]));
}
}
return INF;
}
}G;
int main()
{ #ifndef ONLINE_JUDGE
freopen("YWW.in", "r", stdin);
#endif using namespace Zeonfai;
for(int T = getInt(); T; -- T)
{
int n = getInt(), m = getInt(), k = getInt();
G.build(n);
for(int i = 0; i < m; ++ i)
{
int a = getInt(), b = getInt(), c = getInt(), d = getInt(), w = getInt();
G.link(a, b, c, d, w, n);
}
int ans = G.dijkstra(k);
if(ans == INF)
puts("Yww is our red sun!");
else
println(ans);
}
}

the Red Sun的更多相关文章

  1. 使用CocosSharp制作一个游戏 - CocosSharp中文教程

    注:本教程翻译自官方<Walkthrough - Building a game with CocosSharp>,官方教程有很多地方说的不够详细,或者代码不全,导致无法继续,本人在看了G ...

  2. 20145213《Java程序设计》第三周学习总结

    20145213<Java程序设计>第三周学习总结 教材学习内容总结 正所谓距离产生美,上周我还倾心于Java表面的基础语法.其简单的流程结构,屈指可数的基本类型分类,早已烂熟于心的运算符 ...

  3. 20145206邹京儒《Java程序设计》第3周学习总结

    20145206 <Java程序设计>第3周学习总结 教材学习内容总结 第四章 4.1 定义类 class Clothes{ String color; char size; } publ ...

  4. 20145304 Java第三周学习报告

    20145304 <Java程序设计>第三周学习总结 教材学习内容总结 1.定义类: 类定义时使用class关键词,建立实例要使用new关键词. 代码如下: /*定义类 书上例子 衣服的型 ...

  5. 20145330《Java程序设计》第三周学习总结

    20145330 <Java程序设计>第三周学习总结 第三周知识的难度已经逐步上升,并且一周学习两章学习压力也逐渐加大,需要更高效率的来完成学习内容,合理安排时间. 类与对象 对象(Obj ...

  6. 20145208《Java程序设计》第3周学习总结

    20145208 <Java程序设计>第3周学习总结 教材学习内容总结 认识对象 类类型 在第三章的学习中,我了解到JAVA可区分为基本类型和类类型两种类型,在上周的学习中我学习了JAVA ...

  7. 20145235李涛 《Java程序设计》第3周学习总结

    类与对象 定义类 类是对象的“设计图”,对象是类的实际类型.另外,定义时用class,建实例用new. 通过书上的代码才有所理解: class Clothes { String color; char ...

  8. 20145227 《Java程序设计》第3周学习总结

    20145227 <Java程序设计>第3周学习总结 教材学习内容总结 第四章 认识对象 4.1 类与对象 1.定义类:生活中描述事物无非就是描述事物的属性和行为.如:人有身高,体重等属性 ...

  9. 《Java程序设计》第三周学习总结

    20145224-陈颢文 <Java程序设计>第三周学习总结 教材学习内容总结 一.定义类: ·类定义时使用class关键字,要对类中变量(值域成员/对象数据成员)行类型声明. class ...

随机推荐

  1. HBase官方文档

    HBase官方文档 目录 序 1. 入门 1.1. 介绍 1.2. 快速开始 2. Apache HBase (TM)配置 2.1. 基础条件 2.2. HBase 运行模式: 独立和分布式 2.3. ...

  2. leetcode 【 Maximum Subarray 】python 实现

    题目: Find the contiguous subarray within an array (containing at least one number) which has the larg ...

  3. chrome浏览器设置自动切换代理上网的方法

    利用shadowsocks代理软件实现FQ时,如果都走代理模式,流量肯定不够.可以利用chrome的SwitchyOmega插件实现自动根据URL来决定是否使用代理.设置如下: 1.安装Switchy ...

  4. Python-S9-Day87——admin的使用

    01 admin的使用1 02 admin的使用2 03 admin的使用3 04 url方法的使用 05 单例模式 06 admin源码之注册功能 07 admin源码之url设计 08 admin ...

  5. 更改 Mac 上的功能键行为

    您可以将 Apple 键盘上的顶行按键用作标准功能键,或用来控制 Mac 的内建功能.   如果您的 Apple 键盘部分顶行按键上印有图标,则这些按键可用于执行每个图标所示的特殊功能.这些按键也可用 ...

  6. 收藏网址 jquery学习

    http://www.zhangxinxu.com/wordpress/2009/08/jquery-%E5%8D%95%E5%87%BB%E6%96%87%E5%AD%97%E6%88%96%E5% ...

  7. mybitis中对象字段与表中字段名称不匹配(复制)

    开发中,实体类中的属性名和对应的表中的字段名不一定都是完全相同的,这样可能会导致用实体类接收返回的结果时导致查询到的结果无法映射到实体类的属性中,那么该如何解决这种字段名和实体类属性名不相同的冲突呢? ...

  8. java io 流 输入输出 大牛经典总结

    在软件开发中,数据流和数据库操作占据了一个很重要的位置,所以,熟悉操作数据流和数据库,对于每一个开发者来说都是很重要的,今天就来总结一下I/O,数据库操作 一:从数据流开始 首先先有一个结构图看一下整 ...

  9. HDU 4177 模拟时间问题

    Avoiding a disaster Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  10. Arcengine 基本操作(待更新)

    /// <summary> /// 删除fieldName属性值为1的弧段 /// </summary> /// <param name="fieldName& ...