题:
题意:操作一:点向点连接有向权边,操作二点向线段连有向权边,操作三线段向点连有向权边,问从节点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; }