Codeforces Round #406 (Div. 2) D. Legacy (线段树建图dij)
2 seconds
256 megabytes
standard input
standard output
Rick and his co-workers have made a new radioactive formula and a lot of bad guys are after them. So Rick wants to give his legacy to Morty before bad guys catch them.
There are n planets in their universe numbered from 1 to n. Rick is in planet number s (the earth) and he doesn't know where Morty is. As we all know, Rick owns a portal gun. With this gun he can open one-way portal from a planet he is in to any other planet (including that planet). But there are limits on this gun because he's still using its free trial.
By default he can not open any portal by this gun. There are q plans in the website that sells these guns. Every time you purchase a plan you can only use it once but you can purchase it again if you want to use it more.
Plans on the website have three types:
- With a plan of this type you can open a portal from planet v to planet u.
- With a plan of this type you can open a portal from planet v to any planet with index in range [l, r].
- With a plan of this type you can open a portal from any planet with index in range [l, r] to planet v.
Rick doesn't known where Morty is, but Unity is going to inform him and he wants to be prepared for when he finds and start his journey immediately. So for each planet (including earth itself) he wants to know the minimum amount of money he needs to get from earth to that planet.
The first line of input contains three integers n, q and s (1 ≤ n, q ≤ 105, 1 ≤ s ≤ n) — number of planets, number of plans and index of earth respectively.
The next q lines contain the plans. Each line starts with a number t, type of that plan (1 ≤ t ≤ 3). If t = 1 then it is followed by three integers v, u and w where w is the cost of that plan (1 ≤ v, u ≤ n, 1 ≤ w ≤ 109). Otherwise it is followed by four integers v, l, r and w where w is the cost of that plan (1 ≤ v ≤ n, 1 ≤ l ≤ r ≤ n, 1 ≤ w ≤ 109).
In the first and only line of output print n integers separated by spaces. i-th of them should be minimum money to get from earth to i-th planet, or - 1 if it's impossible to get to that planet.
3 5 1
2 3 2 3 17
2 3 2 2 16
2 2 2 3 3
3 3 1 1 12
1 3 3 17
0 28 12
4 3 1
3 4 1 3 12
2 2 3 4 10
1 2 4 16
0 -1 -1 12
In the first sample testcase, Rick can purchase 4th plan once and then 2nd plan in order to get to get to planet number 2.
【分析】在一条数轴上,某人初始位置在s点,它有三种功能枪,第一种就是 从u点开一条到v点的即时通道,第二种是开一条从u到[l,r]区间任一点的通道,
第三种是开一条从[l,r]区间任一点到v的通道,所有通道都是单向的即时的,而且一种枪买来只能用一次,用完了还想使用的话就得花钱买,然后问从s点到其他各点
的最小花费。
很明显这是个最短路。问题是从一个点到区间,需要将区间所有的点都建边,这样指定超时。看到区间,于是我们想到线段树。。。对于每个区间我们找到它对应的几个根节点,然后建边,注意,这里要建两棵树分别代表 左端点和右端点,然后就是dij了。
#include <cstdio>
#include <map>
#include <algorithm>
#include <vector>
#include <iostream>
#include <set>
#include <queue>
#include <string>
#include <cstdlib>
#include <cstring>
#include <cmath>
using namespace std;
typedef pair<int,int>pii;
typedef long long LL;
const int N=6e6+;
const int mod=1e9+;
int n,m,s,cnt,idl[N<<],idr[N<<];
bool vis[N];
LL d[N];
vector<pii>edg[N];
void buildl(int rt,int l,int r)
{
idl[rt]=++cnt;
if(l==r)return ;
int m=l+r>>;
buildl(rt<<,l,m);
buildl(rt<<|,m+,r);
edg[idl[rt<<]].push_back(make_pair(idl[rt],));
edg[idl[rt<<|]].push_back(make_pair(idl[rt],));
}
void buildr(int rt,int l,int r)
{
idr[rt]=++cnt;
if(l==r)return ;
int m=l+r>>;
buildr(rt<<,l,m);
buildr(rt<<|,m+,r);
edg[idr[rt]].push_back(make_pair(idr[rt<<],));
edg[idr[rt]].push_back(make_pair(idr[rt<<|],));
}
void pre(int rt,int l,int r)
{
if(l==r)
{
edg[l].push_back(make_pair(idl[rt],));
edg[idr[rt]].push_back(make_pair(l,));
return;
}
int m=l+r>>;
pre(rt<<,l,m);
pre(rt<<|,m+,r);
}
void addl(int rt,int l,int r,int L,int R,int w){
if(L<=l&&r<=R){
edg[idl[rt]].push_back(make_pair(cnt,w));
return;
}
int mid=(l+r)/;
if(L<=mid)addl(rt*,l,mid,L,R,w);
if(R>mid)addl(rt*+,mid+,r,L,R,w);
}
void addr(int rt,int l,int r,int L,int R){
if(L<=l&&r<=R){
edg[cnt].push_back(make_pair(idr[rt],));
return;
}
int mid=(l+r)/;
if(L<=mid)addr(rt*,l,mid,L,R);
if(R>mid)addr(rt*+,mid+,r,L,R);
}
struct man{
int v;
LL w;
bool operator<(const man &e)const{
return w>e.w;
}
};
priority_queue<man>q;
void dij(int s){
for(int i=;i<=cnt;i++)d[i]=-,vis[i]=;
d[s]=;
q.push(man{s,});
while(!q.empty()){
int u=q.top().v;q.pop();
if(vis[u])continue;
vis[u]=;
for(int i=;i<edg[u].size();++i){
int v=edg[u][i].first,w=edg[u][i].second;
if(!vis[v]&&(d[v]==-||d[v]>d[u]+w)){
d[v]=d[u]+w;
q.push(man{v,d[v]});
}
}
}
}
int main()
{
int w;
scanf("%d%d%d",&n,&m,&s);
cnt=n;
buildl(,,n);
buildr(,,n);
pre(,,n);
while(m--)
{
++cnt;
int op,l,r,x,y;
scanf("%d",&op);
if(op==)
{
scanf("%d%d%d",&x,&y,&w);
addl(,,n,x,x,w);
addr(,,n,y,y);
}
else if(op==)
{
scanf("%d%d%d%d",&x,&l,&r,&w);
addl(,,n,x,x,w);
addr(,,n,l,r);
}
else
{
scanf("%d%d%d%d",&x,&l,&r,&w);
addl(,,n,l,r,w);
addr(,,n,x,x);
}
}
dij(s);
for(int i=;i<=n;i++)printf("%lld%c",d[i],i==n?'\n':' ');
return ;
}
Codeforces Round #406 (Div. 2) D. Legacy (线段树建图dij)的更多相关文章
- Codeforces Round #406 (Div. 1) B. Legacy 线段树建图跑最短路
B. Legacy 题目连接: http://codeforces.com/contest/786/problem/B Description Rick and his co-workers have ...
- 【转】Codeforces Round #406 (Div. 1) B. Legacy 线段树建图&&最短路
B. Legacy 题目连接: http://codeforces.com/contest/786/problem/B Description Rick and his co-workers have ...
- Codeforces Round #406 (Div. 2) D. Legacy 线段树建模+最短路
D. Legacy time limit per test 2 seconds memory limit per test 256 megabytes input standard input out ...
- Codeforces Round #406 (Div. 2) 787-D. Legacy
Rick and his co-workers have made a new radioactive formula and a lot of bad guys are after them. So ...
- Codeforces Round #603 (Div. 2) E. Editor 线段树
E. Editor The development of a text editor is a hard problem. You need to implement an extra module ...
- Codeforces Codeforces Round #316 (Div. 2) C. Replacement 线段树
C. ReplacementTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/570/problem ...
- Codeforces Round #765 Div.1 F. Souvenirs 线段树
题目链接:http://codeforces.com/contest/765/problem/F 题意概述: 给出一个序列,若干组询问,问给出下标区间中两数作差的最小绝对值. 分析: 这个题揭示着数据 ...
- Codeforces Round #278 (Div. 1) Strip (线段树 二分 RMQ DP)
Strip time limit per test 1 second memory limit per test 256 megabytes input standard input output s ...
- Codeforces Round #271 (Div. 2) E. Pillars 线段树优化dp
E. Pillars time limit per test 1 second memory limit per test 256 megabytes input standard input out ...
随机推荐
- [ZJOI2008]骑士 DP dfs
---题解--- 题解: 观察题面可以很快发现这是一棵基环内向树(然而并没有什么用...) 再稍微思考一下,假设将这个环中的任意一点设为root,然后去掉root到下面的特殊边(即构成环的那条边),那 ...
- Website Collection
前一百个卡特兰数 Candy?的博弈论总结 杜教筛资料 线性基资料 (ex)BSGS资料 斐波那契数列前300项 斯特林数 STL标准库-容器-unordered_set C++ unordered_ ...
- python构建一个项目
二.实验步骤 2.1 实验准备 我们的实验项目名为 factorial. $ mkdir factorial $ cd factorial/ 2.2 主代码 我们给将要创建的 Python 模块取名为 ...
- ext4文件系统由文件的inode号定位其inode Table
在ubuntu中(以16.06为例),stat filename 可以查看文件的inode数值,但是如何确定该inode项具体在哪个块组下的inode Table中不是那么容易,接下来通过一步步计算来 ...
- Java拷贝构造函数初尝试
浅复制(浅克隆) :被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. 深复制(深克隆) :被复制 ...
- bzoj1862: [Zjoi2006]GameZ游戏排名系统
Description GameZ为他们最新推出的游戏开通了一个网站.世界各地的玩家都可以将自己的游戏得分上传到网站上.这样就可以看到自己在世界上的排名.得分越高,排名就越靠前.当两个玩家的名次相同时 ...
- sql 批量更新表中多字段为不同的值
,),,),rand()) select newid() ,) update tablename , FB,)) , ), FC,)) , )
- CVE-2016-6662 mysql RCE测试
参考:http://bobao.360.cn/learning/detail/3027.html ,我尝试第一种方法 1.先修改mysql_hookandroot_lib.c里面的反弹地址和端口: # ...
- 转:Android 调试桥(adb)是多种用途的工具
转自:http://my.oschina.net/xuwa/blog/1574 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态. 可以通过下列几种方法加入 ...
- Swift : missing argument label 'xxx' in call
http://stackoverflow.com/questions/24050844/swift-missing-argument-label-xxx-in-call up vote37down v ...