Legacy
给出一个带权有向图,有三种操作:
1.u->v添加一条权值为w的边
2.区间[l,r]->v添加权值为w的边
3.v->区间[l,r]添加权值为w的边
求st点到每个点的最短路
#include
#include
#include
#include
#include
#include
#define File(x) "test."#x
#define For(i,s,e) for(int i=(s); i<=(e); i++)
#define Rep(i,s,e) for(int i=(s); i>=(e); i--)
#define LSON o<<1, l, mid
#define RSON o<<1|1, mid+1, r
using namespace std;
const int N=1000000+1;
typedef long long LL;
struct Node{
int x;
LL w;
bool operator < (const Node & o) const {
return w>o.w;
}
};
int q,n,s,maxo;
vector v[N];
void addEdge(int x, int y, LL w){
v[x].push_back((Node){y,w});
}
void build_p_seg(int o, int l, int r){//点到区间
maxo=max(maxo, o);
if(l==r){
addEdge(o+n, l, 0);//
return;
}
int mid=(l+r)>>1;
build_p_seg(LSON); build_p_seg(RSON);
addEdge(o+n, (o<<1)+n, 0); addEdge(o+n, (o<<1|1)+n, 0);//
}
void build_seg_p(int o, int l, int r){
if(l==r){
addEdge(l, o+n+maxo, 0);//
return;
}
int mid=(l+r)>>1;
build_seg_p(LSON); build_seg_p(RSON);
addEdge((o<<1)+maxo+n, o+maxo+n, 0); addEdge((o<<1|1)+maxo+n, o+maxo+n, 0);//
}
void add_p_seg(int x, LL w, int L, int R, int o, int l, int r){
if(L<=l && r<=R){
addEdge(x, o+n, w); return;
}
int mid=(l+r)>>1;
if(L<=mid) add_p_seg(x, w, L, R, LSON);
if(R>mid) add_p_seg(x, w, L, R, RSON);
}
void add_seg_p(int x, LL w, int L, int R, int o, int l, int r){
if(L<=l && r<=R){
addEdge(o+maxo+n, x, w); return;
}
int mid=(l+r)>>1;
if(L<=mid) add_seg_p(x, w, L, R, LSON);
if(R>mid) add_seg_p(x, w, L, R, RSON);
}
LL dis[N],inf=5000000000LL*500000;
bool used[N];
void dij(){
priority_queueq;
For(i,1,n+2*maxo) dis[i]=inf;
dis[s]=0; q.push((Node){s,0});
while(!q.empty()){
int x=q.top().x; q.pop();
if(used[x]) continue;
used[x]=1;
if(!v[x].empty())
for(int p=0; pint u=point.x;
if(dis[u]>dis[x]+point.w){
dis[u]=dis[x]+point.w;
q.push((Node){u,dis[u]});
}
}
}
}
int main()
{
freopen(File(in),"r",stdin);
freopen(File(out),"w",stdout);
// ios::sync_with_stdio(false);
scanf("%d%d%d",&n,&q,&s);
build_p_seg(1,1,n);
build_seg_p(1,1,n);
while(q--){
int opt,x,y,l,r;
LL w;
scanf("%d",&opt);
if(opt==1){
scanf("%d%d%lld",&x,&y,&w);
if(x!=y) addEdge(x,y,w);
}
else if(opt==2){
scanf("%d%d%d%lld",&x,&l,&r,&w);
add_p_seg(x,w,l,r,1,1,n);
}
else{
scanf("%d%d%d%lld",&x,&l,&r,&w);
add_seg_p(x,w,l,r,1,1,n);
}
}
dij();
For(i,1,n) printf("%lld ",dis[i]==inf?-1:dis[i]);
puts("");
return 0;
}