【题目链接】 http://codeforces.com/problemset/problem/786/B

【题目大意】

  给出一些星球,现在有一些传送枪,可以从一个星球到另一个星球,
  从一个星球到另一些星球,或者从一些星球到某个星球,每种传送枪使用一次要花费不同的价格
  地球是其中一个星球,问从地球到其它星球的最少花费是多少

【题解】

  因为一个星球到一些星球和一些星球到某个星球是以区间形式给出的,
  所以我们可以用线段树建图优化,对点进行压缩,
  建立两颗线段树表示有向线段左端和右端的合并情况,之后在优化后的图上跑最短路即可。

【代码】

#include <cstdio>
#include <algorithm>
#include <utility>
#include <vector>
#include <queue>
using namespace std;
const int N=100010;
const int V=N*5;
int n,m,s;
vector<pair<int,int> >G[V];
void addedge(int u,int v,int c){G[u].push_back(make_pair(v,c));}
int id[2][N<<2],idx;
void build(int x,int l,int r,int k){
id[k][x]=++idx;
if(l==r){
if(k==0)addedge(id[k][x],l,0);
else addedge(l,id[k][x],0);
return;
}
int mid=(l+r)>>1;
build(x<<1,l,mid,k);
build(x<<1|1,mid+1,r,k);
if(k==0){
addedge(id[k][x],id[k][x<<1],0);
addedge(id[k][x],id[k][x<<1|1],0);
}else{
addedge(id[k][x<<1],id[k][x],0);
addedge(id[k][x<<1|1],id[k][x],0);
}
}
vector<int> vs;
void get(int x,int l,int r,int L,int R,int k){
if(L<=l&&r<=R){
vs.push_back(id[k][x]);
return;
}
int mid=(l+r)>>1;
if(L<=mid)get(x<<1,l,mid,L,R,k);
if(R>mid)get(x<<1|1,mid+1,r,L,R,k);
}
typedef long long LL;
const LL LLINF=0x3f3f3f3f3f3f3f3fLL;
LL dis[V]; bool vis[V];
void Dijkstra(int s){
for(int i=1;i<=5*n;i++)vis[i]=0,dis[i]=LLINF;
priority_queue<pair<LL,int> > q;
q.push(make_pair(-0,s)); dis[s]=0;
while(!q.empty()){
int u=q.top().second; q.pop();
if(vis[u])continue;
vis[u]=1;
for(int i=0;i<G[u].size();i++){
int v=G[u][i].first,c=G[u][i].second;
if(dis[v]>dis[u]+c){
dis[v]=dis[u]+c;
q.push(make_pair(-dis[v],v));
}
}
}
}
int main(){
while(~scanf("%d%d%d",&n,&m,&s)){
for(int i=0;i<=5*n;i++)G[i].clear();
idx=n;
build(1,1,n,0); build(1,1,n,1);
while(m--){
int t,u;
scanf("%d%d",&t,&u);
if(t==1){
int v,c; scanf("%d%d",&v,&c);
addedge(u,v,c);
}else if(t==2){
vs.clear();
int l,r,c; scanf("%d%d%d",&l,&r,&c);
get(1,1,n,l,r,0);
for(int i=0;i<vs.size();i++)addedge(u,vs[i],c);
}else{
vs.clear();
int l,r,c; scanf("%d%d%d",&l,&r,&c);
get(1,1,n,l,r,1);
for(int i=0;i<vs.size();i++)addedge(vs[i],u,c);
}
}Dijkstra(s);
for(int i=1;i<=n;i++){
if(dis[i]==LLINF)dis[i]=-1;
printf("%lld%c",dis[i],i==n?'\n':' ');
}
}return 0;
}

CodeForces 786B Legacy(线段树优化建图+最短路)的更多相关文章

  1. Codeforces.786B.Legacy(线段树优化建图 最短路Dijkstra)

    题目链接 \(Description\) 有\(n\)个点.你有\(Q\)种项目可以选择(边都是有向边,每次给定\(t,u,v/lr,w\)): t==1,建一条\(u\to v\)的边,花费\(w\ ...

  2. codeforces 787D - Legacy 线段树优化建图,最短路

    题意: 有n个点,q个询问, 每次询问有一种操作. 操作1:u→[l,r](即u到l,l+1,l+2,...,r距离均为w)的距离为w: 操作2:[l,r]→u的距离为w 操作3:u到v的距离为w 最 ...

  3. CF786B Legacy 线段树优化建图 + spfa

    CodeForces 786B Rick和他的同事们做出了一种新的带放射性的婴儿食品(???根据图片和原文的确如此...),与此同时很多坏人正追赶着他们.因此Rick想在坏人们捉到他之前把他的遗产留给 ...

  4. G. 神圣的 F2 连接着我们 线段树优化建图+最短路

    这个题目和之前写的一个线段树优化建图是一样的. B - Legacy CodeForces - 787D 线段树优化建图+dij最短路 基本套路 之前这个题目可以相当于一个模板,直接套用就可以了. 不 ...

  5. [Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路)

    [Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路) 题面 有n个空心物品,每个物品有外部体积\(out_i\)和内部体积\(in_i\),如果\(in_i& ...

  6. BZOJ5017 [SNOI2017]炸弹 - 线段树优化建图+Tarjan

    Solution 一个点向一个区间内的所有点连边, 可以用线段树优化建图来优化 : 前置技能传送门 然后就得到一个有向图, 一个联通块内的炸弹可以互相引爆, 所以进行缩点变成$DAG$ 然后拓扑排序. ...

  7. 【BZOJ3681】Arietta 树链剖分+可持久化线段树优化建图+网络流

    [BZOJ3681]Arietta Description Arietta 的命运与她的妹妹不同,在她的妹妹已经走进学院的时候,她仍然留在山村中.但是她从未停止过和恋人 Velding 的书信往来.一 ...

  8. 【ARC069F】Flags 2-sat+线段树优化建图+二分

    Description ​ 数轴上有 n 个旗子,第 ii 个可以插在坐标 xi或者 yi,最大化两两旗子之间的最小距离. Input ​ 第一行一个整数 N. ​ 接下来 N 行每行两个整数 xi, ...

  9. 【bzoj5017】[Snoi2017]炸弹 线段树优化建图+Tarjan+拓扑排序

    题目描述 在一条直线上有 N 个炸弹,每个炸弹的坐标是 Xi,爆炸半径是 Ri,当一个炸弹爆炸时,如果另一个炸弹所在位置 Xj 满足:  Xi−Ri≤Xj≤Xi+Ri,那么,该炸弹也会被引爆.  现在 ...

随机推荐

  1. 动态规划:数位DP

    数位dp一般应用于: 求出在给定区间[A,B]内,符合条件P(i)的数i的个数 条件P(i)一般与数的大小无关,而与 数的组成 有关 例题是一道BZOJ1833,让求出区间所有整数每个数字出现的次数 ...

  2. 【spoj1811 & spoj1812 - LCS1 & LCS2】sam

    spoj1811  给两个长度小于100000的字符串 A 和 B,求出他们的最长公共连续子串. 先将串 A 构造为 SAM ,然后用 B 按如下规则去跑自动机.用一个变量 lcs 记录当前的最长公共 ...

  3. bzoj 4999: This Problem Is Too Simple!

    Description 给您一颗树,每个节点有个初始值. 现在支持以下两种操作: 1. C i x(0<=x<2^31) 表示将i节点的值改为x. 2. Q i j x(0<=x&l ...

  4. bzoj2442&&codevs4654 单调队列优化dp

    这道题也是一道单调队列 很明显满足各种性质 f[i]表示i不选前面k-1个都选的最小损失 维护的是个单增队列 q[head]是队列最小值 代码十分简介 注意longlong就okay #include ...

  5. bzoj 1002 找规律(基尔霍夫矩阵)

    网上说的是什么基尔霍夫矩阵,没学过这个,打个表找下规律,发现 w[i]=3*w[i-1]-w[i-2]+2; 然后写个高精直接递推就行了 //By BLADEVIL var n :longint; a ...

  6. 基于SSM框架web搜索功能的实现

    这里适合选用于jsp搭建的网站,数据库采用MySQL 一.HTML <div class="header_search"> <input type="t ...

  7. [转]如何整理Linux磁盘碎片,竟与Windows的方式大不同 返回操作系统首页

    Linux 系统永远不需要整理磁盘碎片的神话相信很多人都听说过.由于 Linux 采用了优秀的日志文件系统(ext2.ext3.ext4, btrfs等),在绝大多数情况下确实是不需要进行磁盘碎片整理 ...

  8. [转]树莓派gpio口控制

    0.前言     树莓派现在越来越火,网上树莓派的资料也越来越多.树莓派源自英国,国外嵌入式开源领域具有良好的分享精神,树莓派各种集成库也层出不穷,下面推荐几个. [[开发语言]——python [[ ...

  9. php使用curl模拟登录带验证码的网站

    需求是这样的,需要登录带验证码的网站,获取数据,但是不可能人为一直去记录数据,想通过自动采集的方式进行,如下是试验出来的结果代码!有需要的可以参考下! <?php namespace Home\ ...

  10. JAVA Eclipse 教程

    http://www.runoob.com/eclipse/eclipse-tutorial.html