1. 程式人生 > 實用技巧 >Legacy(點對線段有路走,線段向點有路走,線段樹走dij)

Legacy(點對線段有路走,線段向點有路走,線段樹走dij)

題:

題意:操作一:點向點連線有向權邊,操作二點向線段連有向權邊,操作三線段向點連有向權邊,問從節點s開始的最短路

分析:建倆棵線段樹,葉子節點作為共同點,操作一就是葉子節點,操作二和三就分別在倆個線段樹裡,然後跑dij;

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define MP make_pair
#define lson root<<1,l,midd
#define rson root<<1|1,midd+1,r
typedef long long ll;
const ll INF=1e18; const int M=1e6+6; int id1[M],id2[M],tot; vector< pair<int,ll> >g[M]; int build1(int root,int l,int r){ if(l==r){ id1[root]=l; return id1[root]; } id1[root]=++tot; int midd=(l+r)>>1; int lid=build1(lson); int rid=build1(rson); g[lid].pb(MP(id1[root],
0)); g[rid].pb(MP(id1[root],0)); return id1[root]; } int build2(int root,int l,int r){ if(l==r){ id2[root]=l; return id2[root]; } id2[root]=++tot; int midd=(l+r)>>1; int lid=build2(lson); int rid=build2(rson); g[id2[root]].pb(MP(lid,0)); g[id2[root]].pb(MP(rid,
0)); return id2[root]; } void update2(int u,int L,int R,ll w,int root,int l,int r){///操作二,點向線段連邊 if(L<=l&&r<=R){ g[u].pb(MP(id2[root],w)); return ; } int midd=(l+r)>>1; if(L<=midd) update2(u,L,R,w,lson); if(R>midd) update2(u,L,R,w,rson); } void update1(int L,int R,int u,ll w,int root,int l,int r){///操作三,線段向點連邊 if(L<=l&&r<=R){ g[id1[root]].pb(MP(u,w)); return ; } int midd=(l+r)>>1; if(L<=midd) update1(L,R,u,w,lson); if(R>midd) update1(L,R,u,w,rson); } struct node{ int v; ll w; node(int v,ll w):v(v),w(w){} bool operator < (const node &b)const{ return w>b.w; } }; int vis[M]; ll dis[M]; priority_queue<node>que; void Dij(int st,int n){ for(int i=0;i<=n;i++) dis[i]=INF; que.push(node(st,0)); dis[st]=0; while(!que.empty()){ node now=que.top(); que.pop(); int u=now.v; if(vis[u]) continue; vis[u]=1; for(int i=0;i<(int)g[u].size();i++){ int v=g[u][i].first; ll w=g[u][i].second; if(!vis[v]&&dis[v]>dis[u]+w){ dis[v]=dis[u]+w; que.push(node(v,dis[v])); } } } } int main(){ int n,m,s; scanf("%d%d%d",&n,&m,&s); tot=n; build1(1,1,n); build2(1,1,n); for(int op,v,u,l,r,i=1;i<=m;i++){ ll w; scanf("%d%d",&op,&u); if(op==1){ scanf("%d%lld",&v,&w); g[u].pb(MP(v,w)); } else if(op==2){ scanf("%d%d%lld",&l,&r,&w); update2(u,l,r,w,1,1,n); } else{ scanf("%d%d%lld",&l,&r,&w); update1(l,r,u,w,1,1,n); } } Dij(s,n+tot); for(int i=1;i<=n;i++) printf("%lld ",(dis[i]==INF ? -1 :dis[i])); return 0; }
View Code