题意:给N个点和Q条选项,有三种类型的选项:1.从u到v花费w修建一条路;2.从u到下标区间为[L,R]的点花费w修建一条路; 3.从下标区间为[L,R]的点到u花费w修建一条路。

然后求起点s到其余点的最短路。

如果直接暴力建图,建图本身就会超时。对于区间上的操作,考虑用线段树解决。线段树上的结点本身就能代表一段区间的点,所以在建图时,用树上的结点充当中间结点。(有点网络流的思想?)

因为要建一张有向图,所以图的点到树上结点要连边,反之亦然;但是在一棵线段树上双向连边就不能对所有的点跑最短路了(因为图中的点可能会在树上找到权值为0的回路回到自己)。

所以再建一棵线段树去表示反向连边的关系。

对每个树上结点从N+1开始编号,将其与之维护的区间中的点连一条花费为0的边。每次更新就是用把给定区间[L,R]囊括的所有树上结点与给定的u连边。操作2和操作3分别对应两棵线段树的结点。

#include<bits/stdc++.h>
#define lson rt<<1
#define rson rt<<1|1
#define Lson l,m,lson
#define Rson m+1,r,rson
using namespace std;
typedef long long LL;
const int maxn = 4e5+;
const LL INF = (1LL)<<;
struct Edge{
int to,next;
LL w;
}edges[maxn<<];
int head[maxn<<],tot;
int ID[maxn<<],rID[maxn<<];
int id; void init(int N)
{
memset(head,-,sizeof(head));
tot=;
id = N;
} void AddEdge(int u,int v,LL w){
edges[tot] = (Edge){v,head[u],w};
head[u] = tot++;
} void build(int l,int r,int rt,bool flag)
{
if(!flag) ID[rt] = ++id;
else rID[rt] = ++id;
if(!flag) {for(int i=l;i<=r;++i) AddEdge(ID[rt],i,);}
else {for(int i=l;i<=r;++i) AddEdge(i,rID[rt],);}
if(l==r) return;
int m = (l+r)>>;
build(Lson,flag);
build(Rson,flag);
} void update(int L,int R,LL w,int u,int l,int r,int rt,bool flag)
{
if(L<=l && R>=r){
if(!flag)AddEdge(u,ID[rt],w);
else AddEdge(rID[rt],u,w);
return;
}
int m =(l+r)>>;
if(L<=m) update(L,R,w,u,Lson,flag);
if(R>m) update(L,R,w,u,Rson,flag);
} LL d[maxn<<];
bool used[maxn<<];
struct HeapNode{
LL d;
int u;
bool operator <(const HeapNode & rhs) const {return d > rhs.d;}
};
void dijkstra(int s){
memset(used,,sizeof(used));
priority_queue<HeapNode> Q;
for(int i=;i<=id;++i) d[i]=INF;
d[s]=;
Q.push((HeapNode){,s});
while(!Q.empty()){
HeapNode x =Q.top();Q.pop();
int u =x.u;
if(used[u]) continue;
used[u]= true;
for(int i=head[u];~i;i=edges[i].next){
Edge & e = edges[i];
if(d[e.to] > d[u] + e.w){
d[e.to] = d[u] +e.w;
Q.push((HeapNode){d[e.to],e.to});
}
}
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int T,N,M,q,s,u,v,op,L,R;
LL w;
while(scanf("%d%d%d",&N,&q,&s)==){
init(N);
build(,N,,);
build(,N,,);
while(q--){
scanf("%d",&op);
if(op==){
scanf("%d%d%lld",&u,&v,&w);
AddEdge(u,v,w);
}
else if(op==){
scanf("%d%d%d%lld",&u,&L,&R,&w);
update(L,R,w,u,,N,,);
}
else{
scanf("%d%d%d%lld",&u,&L,&R,&w);
update(L,R,w,u,,N,,);
}
}
dijkstra(s);
for(int i=;i<=N;++i)
printf("%lld%c",d[i]==INF?-:d[i],i==N?'\n':' ');
}
return ;
}

CodeForces - 786B Legacy (线段树+DIjkstra+思维)的更多相关文章

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

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

  2. Codeforces 786B. Legacy 线段树+spfa

    题目大意: 给定一个\(n\)的点的图.求\(s\)到所有点的最短路 边的给定方式有三种: \(u \to v\) \(u \to [l,r]\) \([l,r] \to v\) 设\(q\)为给定边 ...

  3. Codeforces 787D. Legacy 线段树建模+最短路

    D. Legacy time limit per test:2 seconds memory limit per test:256 megabytes input:standard input out ...

  4. 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 最 ...

  5. Codeforces 787D Legacy 线段树 最短路

    题意: 有\(n(1 \leq n \leq 10^5)\)个点,\(q(1 \leq q \leq 10^5)\)条路和起点\(s\) 路有三种类型: 从点\(v\)到点\(u\)需要花费\(w\) ...

  6. 786B - Legacy(线段树 + 最短路)线段树优化建图

    题意: 就是给定一张n nn个点的图,求源点s ss到每个点的单源最短路.这张图共有q组边,连边方式有3种: a→b ,边权为w的单向边:a→[l,r] ,即a到连续区间[l,r]中的每一个点都有一条 ...

  7. [Educational Codeforces Round 81 (Rated for Div. 2)]E. Permutation Separation(线段树,思维,前缀和)

    [Educational Codeforces Round 81 (Rated for Div. 2)]E. Permutation Separation(线段树,思维,前缀和) E. Permuta ...

  8. CodeForces 786B Legacy(线段树优化建图+最短路)

    [题目链接] http://codeforces.com/problemset/problem/786/B [题目大意] 给出一些星球,现在有一些传送枪,可以从一个星球到另一个星球, 从一个星球到另一 ...

  9. Codeforces 786B Legacy(线段树优化建图)

    题目链接  Legacy 首先对于输入的$n$,建立一棵线段树. 显然线段树有大概$2n$个结点,每个节点对应一段区间 我们把这$2n$个结点加入我们的无向图中,一起跑最短路. 具体连边方案: 我们把 ...

随机推荐

  1. 阐述二维码的原理以及使用google api和PHP QR Code来生成二维码

    一.什么是二维码:二维码 (2-dimensional bar code),是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的.在许多种类的二维条码中,常用的码 ...

  2. 说明Oracle数据库逻辑备份和物理备份的方式。

    说明Oracle数据库逻辑备份和物理备份的方式. 解答:Oracle备份包括逻辑备份和物理备份. 1).逻辑备份 数据库的逻辑备份包含读一个数据库记录集和将记录集写入文件. a.输出(Export)输 ...

  3. Struts2包含哪些标签?

    Struts2包含哪些标签? 解答: A: <s:a href=”"></s:a>—–超链接,类似于html里的<a></a> <s:a ...

  4. js Date操作

    new Date(new Date().getTime() - 24 * 24 * 60 * 60 * 1000)类似C#中的AddDays,返回一个月前的时间  //时间格式化方法        v ...

  5. hdu 2117:Just a Numble(水题,模拟除法运算)

    Just a Numble Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tot ...

  6. JB开发之三 [jailbreak,越狱技术积累]

    很兴奋,我开始了进行JB的开发 1.杀死当前的APP [(SpringBoard *)[UIApplicationsharedApplication] _killThermallyActiveAppl ...

  7. 面试题思考: 什么是事务(ACID)?

    事务(Transaction)是由一系列对系统中数据进行访问与更新的操作所组成的一个程序 执行逻辑单元(Unit). 狭义上的事务特指数据库事务.一方面,当多个应用程序并发访问数据库时,事务可以在这些 ...

  8. SQL转换全角和半角函数

    SQL转换全角和半角函数 CREATE FUNCTION f_Convert( ), --要转换的字符串 @flag bit --转换标志,0转换成半角,1转换成全角 )) AS BEGIN ),@s ...

  9. angular-ui-bootstrap 日历控件国际化

    angularjs-angular-ui-bootstrap-changing-language http://stackoverflow.com/questions/19671887/angular ...

  10. 《JAVA多线程编程核心技术》 笔记:第三章:线程间通信

    一. 等待/通知机制:wait()和notify()1.1.使用的原因:1.2 具体实现:wait()和notify()1.2.1 方法wait():1.2.2 方法notify():1.2.3 wa ...