题面:786B - Legacy

代码:

 

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<iostream>
  4 #include<queue>
  5 #define ll long long
  6 using namespace std;
  7 inline ll rd(){
  8     ll x=0,f=1;char c=getchar();
  9     while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
 10     while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
 11     return f*x;
 12 }
 13 const int maxn=(1e5)+50,maxq=maxn;
 14 const ll inf=1ll<<60;
 15 int N,S,Q,o,v,u,ql,qr,num_edge=0,edge_head[maxn*15];
 16 int tr[maxn*15][3],cnt;
 17 ll w,Dis[maxn*15];
 18 bool vis[maxn*15];
 19 struct Num_{
 20     int id;ll dis;
 21     bool operator < (const Num_&a) const{
 22         return a.dis<dis;
 23     }
 24 }e;
 25 priority_queue<Num_>pri;
 26 struct Edge{ int to,nx; ll dis; }edge[maxn*40];
 27 inline void Add_edge(int from,int to,int dis){
 28     edge[++num_edge].nx=edge_head[from];
 29     edge[num_edge].to=to;
 30     edge[num_edge].dis=dis;
 31     edge_head[from]=num_edge;
 32     return;
 33 }
 34 void Build(int x,int l,int r){
 35     if(l==r){
 36         tr[x][0]=tr[x][1]=l;
 37         return;
 38     }
 39     int m=(l+r)>>1;
 40     tr[x][0]=++cnt; tr[x][1]=++cnt;
 41     Build(x<<1,l,m); Build(x<<1|1,m+1,r);
 42     Add_edge(tr[x][0],tr[x<<1][0],0);
 43     Add_edge(tr[x][0],tr[x<<1|1][0],0);
 44     Add_edge(tr[x<<1][1],tr[x][1],0);
 45     Add_edge(tr[x<<1|1][1],tr[x][1],0);
 46     return;
 47 }
 48 void Update(int x,int l,int r,int ql,int qr,int u,int val,int op){
 49     if(ql<=l&&r<=qr){
 50         if(op==0) Add_edge(u,tr[x][0],val);
 51         else Add_edge(tr[x][1],u,val);
 52         return;
 53     }
 54     int m=(l+r)>>1;
 55     if(ql<=m)Update(x<<1,l,m,ql,qr,u,val,op);
 56     if(qr>m)Update(x<<1|1,m+1,r,ql,qr,u,val,op);
 57     return;
 58 }
 59 inline void Dijkstra(int s){
 60     for(int i=1;i<=cnt;i++)Dis[i]=inf;
 61     Dis[s]=0;
 62     e.id=s;e.dis=0;
 63     pri.push(e);
 64     while(!pri.empty()){
 65         int x=(pri.top()).id;
 66         pri.pop();
 67         if(vis[x])continue;
 68         vis[x]=1;
 69         for(int i=edge_head[x];i;i=edge[i].nx){
 70             int y=edge[i].to;
 71             if(Dis[x]+edge[i].dis<Dis[y]){
 72                 Dis[y]=Dis[x]+edge[i].dis;
 73                 e.id=y;e.dis=Dis[y];
 74                 pri.push(e);
 75             }
 76         }
 77     }
 78     return;
 79 }
 80 int main(){
 81     N=rd();Q=rd();S=rd();
 82     cnt=N;
 83     Build(1,1,N);
 84     while(Q--){
 85         o=rd();
 86         if(o==1){
 87             v=rd();u=rd();w=rd();
 88             Add_edge(v,u,w);
 89         }
 90         else {
 91             v=rd();ql=rd();qr=rd();w=rd();
 92             if(o==2)
 93                 Update(1,1,N,ql,qr,v,w,0);
 94             else//o==3
 95                 Update(1,1,N,ql,qr,v,w,1);
 96         }
 97     }
 98     Dijkstra(S);
 99     for(int i=1;i<=N;i++)
100         if(Dis[i]!=inf)printf("%lld ",Dis[i]);
101         else printf("-1 ");
102     return 0;
103 }
邻接表建图版

相关文章: