zoukankan      html  css  js  c++  java
  • CF-787D-线段树建图+最短路

    http://codeforces.com/problemset/problem/787/D

        题目大意是给出一个有向图,有N个节点,初始节点在S,询问S到所有点最短路。边的读入方式有三种, 1 u v w  表示 u->v有一条边权为w的边, 2 v l r w ,表示v->[l,r]内的任意一个点支付w即可,

    3 v l r w 表示从[l,r]内任意一个点到v支付w即可。直接构图的话可能会出现完全图,被卡死。

      一种巧妙的构图方式是,由这些个区间联想到线段树(然而我并没有想到),我们不妨对2,3两种类型建立两颗线段树 他们的叶子节点是共用的(1--N),对于2来说,如果节点v到树上的某个节点x有一条w的边,

    就表示v到这个节点所对应的区间的点都可以支付w到达,并且在2的内部所有的父亲都向自己的儿子建立一条边权为0的边,这样如果v能到达x,说明v能到达x所有的子孙节点(支付w),对于3来说只不过反过来了一下思路一样。

      建完图之后跑最短路就好了,节点数大约N*10够了。

      

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define LL long long
      4 #define ULL unsigned long long
      5 #define pii pair<int,int>
      6 #define mid ((L+R)>>1)
      7 #define lc (id<<1)
      8 #define rc (id<<1|1)
      9 #define pb push_back
     10 #define mp make_pair
     11 #define inf 0x3f3f3f3f
     12 #define linf 0xffffffffffff
     13 const int maxn=100010;
     14 int N,Q,S,T0,T1,CNT;
     15 int ch[maxn*10][2];
     16 LL d[maxn*10];
     17 bool in[maxn*10];
     18 int tot,first[maxn*10];
     19 struct Edge{int v,w,next;}e[maxn*20];
     20 void add(int u,int v,int w){
     21     e[tot].v=v;
     22     e[tot].w=w;
     23     e[tot].next=first[u];
     24     first[u]=tot++;
     25 }
     26 void build1(int &p,int L,int R){
     27     if(L==R) p=L;
     28     else{
     29         p=++CNT;
     30         build1(ch[p][0],L,mid),build1(ch[p][1],mid+1,R);
     31         add(p,ch[p][0],0),add(p,ch[p][1],0);
     32     }
     33 }
     34 
     35 void build2(int &p,int L,int R){
     36     if(L==R) p=L;
     37     else{
     38         p=++CNT;
     39         build2(ch[p][0],L,mid),build2(ch[p][1],mid+1,R);
     40         add(ch[p][0],p,0),add(ch[p][1],p,0);
     41     }
     42 }
     43 void insert1(int id,int L,int R,int v,int l,int r,int w){
     44     if(L>=l&&R<=r){
     45         add(v,id,w);
     46         return;
     47     }
     48     if(l<=mid)insert1(ch[id][0],L,mid,v,l,r,w);
     49     if(r>mid)insert1(ch[id][1],mid+1,R,v,l,r,w);
     50 }
     51 
     52 void insert2(int id,int L,int R,int v,int l,int r,int w){
     53     if(L>=l&&R<=r){
     54         add(id,v,w);
     55         return;
     56     }
     57     if(l<=mid)insert2(ch[id][0],L,mid,v,l,r,w);
     58     if(r>mid)insert2(ch[id][1],mid+1,R,v,l,r,w);
     59 }
     60 void spfa(){
     61     for(int i=0;i<=CNT;++i)d[i]=linf;
     62     memset(in,0,sizeof(in));
     63     queue<int>q;
     64     q.push(S);
     65     in[S]=1;
     66     d[S]=0;
     67     while(!q.empty()){
     68         int u=q.front();
     69         q.pop();
     70         for(int i=first[u];~i;i=e[i].next){
     71             if(d[e[i].v]>d[u]+e[i].w){
     72                 d[e[i].v]=d[u]+e[i].w;
     73                 if(!in[e[i].v]){
     74                     q.push(e[i].v);
     75                 }
     76             }
     77         }
     78     }
     79     for(int i=1;i<=N;++i) printf("%lld%c",d[i]==linf?-1:d[i],i==N?'
    ':' ');
     80 }
     81 int main()
     82 {
     83     memset(first,-1,sizeof(first));
     84     tot=0;
     85     scanf("%d%d%d",&N,&Q,&S);
     86     CNT=N;
     87     build1(T0,1,N);
     88     build2(T1,1,N);
     89     int opt,u,v,w,l,r;
     90     while(Q--){
     91         scanf("%d",&opt);
     92         if(opt==1){
     93             scanf("%d%d%d",&u,&v,&w);
     94             add(u,v,w);
     95         }
     96         else{
     97             scanf("%d%d%d%d",&v,&l,&r,&w);
     98             if(opt==2){
     99                 insert1(T0,1,N,v,l,r,w);
    100             }
    101             else{
    102                 insert2(T1,1,N,v,l,r,w);
    103             }
    104         }
    105     }
    106     spfa();
    107     return 0;
    108 }
    109 /*0 -1-112
    110 0 -1 -1 12
    111 */
  • 相关阅读:
    POJ 1182 食物链 并查集
    POJ 3666 Making the Grade DP
    POJ 1631 Bridging signals DP(最长上升子序列)
    POJ 1065 Wooden Sticks / hdu 1257 最少拦截系统 DP 贪心
    利用UUID 随机生成8位短号
    JS遍历子孙树
    前端中this的用法
    利用fetch进行POST传参
    SQL UNION 操作符
    Python 抖音机器人,论如何在抖音上找到漂亮小姐姐?
  • 原文地址:https://www.cnblogs.com/zzqc/p/9900367.html
Copyright © 2011-2022 走看看