• HDU 5669 线段树优化建图+分层图最短路


    用线段树维护建图,即把用线段树把每个区间都标号了,Tree1中子节点有到达父节点的单向边,Tree2中父节点有到达子节点的单向边.

    每次将源插入Tree1,汇插入Tree2,中间用临时节点相连。那么Tree1中的所用子节点都可以到达,Tree2中的所用子节点。 

    感觉很有道理啊,以前从来没用用线段树这样维护过建图。分层图最短路没有像BZOJ2763可以直接向先一层连边,因为边已经很多了。

      1 #include <cstdio>
      2 #include <iostream>
      3 #include <cstring>
      4 #include <algorithm>
      5 #include <queue>
      6 #include <vector>
      7 #define pa pair<int,int>
      8 #define pa3 pair<int,pa>
      9 #define mp make_pair
     10 #define fi first
     11 #define se second
     12 #define pb push_back
     13 using namespace std;
     14 const int Maxn=800010;
     15 const int Maxk=12;
     16 struct Edge{int to,next,w;}edge[Maxn<<5];
     17 vector<int> P1,P2;
     18 priority_queue<pa3,vector<pa3>,greater<pa3> > Q;
     19 int n,m,Id1[Maxn],Id2[Maxn],head[Maxn],dis[Maxn][Maxk],cnt,Block;
     20 int Kase,v,k;
     21 inline void Add(int u,int v,int w)
     22 {edge[cnt].to=v;edge[cnt].next=head[u];edge[cnt].w=w;head[u]=cnt++;}
     23 inline int Max(int x,int y) {return x>y?x:y;}
     24 inline void Get_Int(int &x)
     25 {
     26     x=0;  char ch=getchar(); int f=1;
     27     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
     28     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} x*=f;
     29 }
     30 inline void Put_Int(int x)
     31 {
     32     char ch[20]; int top=0;
     33     if (x==0) ch[++top]='0';
     34     while (x) ch[++top]=x%10+'0',x/=10;
     35     while (top) putchar(ch[top--]); putchar('
    ');
     36 }
     37 void Build1(int o,int l,int r)
     38 {
     39     Block=Max(Block,o);
     40     if (l==r) {Id1[l]=o; return;}
     41     int mid=(l+r)>>1;
     42     Build1(o<<1,l,mid),Build1(o<<1|1,mid+1,r);
     43     Add(o<<1,o,0),Add(o<<1|1,o,0);
     44 }
     45 void Build2(int o,int l,int r)
     46 {
     47     if (l==r) {Id2[l]=Block+o; Add(Id2[l],Id1[l],0);return;}
     48     int mid=(l+r)>>1;
     49     Build2(o<<1,l,mid),Build2(o<<1|1,mid+1,r);
     50     Add(Block+o,Block+(o<<1),0),Add(Block+o,Block+(o<<1|1),0);
     51 }
     52 void Modify1(int o,int l,int r,int p,int q)
     53 {
     54     if (l==p && r==q) {P1.pb(o); return;}
     55     int mid=(l+r)>>1;
     56     if (q<=mid) Modify1(o<<1,l,mid,p,q);
     57     if (p>=mid+1) Modify1(o<<1|1,mid+1,r,p,q);
     58     if (p<=mid && q>=mid+1) 
     59     Modify1(o<<1,l,mid,p,mid),Modify1(o<<1|1,mid+1,r,mid+1,q);
     60 }
     61 void Modify2(int o,int l,int r,int p,int q)
     62 {
     63     if (l==p && r==q) {P2.pb(o+Block); return;}
     64     int mid=(l+r)>>1;
     65     if (q<=mid) Modify2(o<<1,l,mid,p,q);
     66     if (p>=mid+1) Modify2(o<<1|1,mid+1,r,p,q);
     67     if (p<=mid && q>=mid+1)
     68     Modify2(o<<1,l,mid,p,mid),Modify2(o<<1|1,mid+1,r,mid+1,q);
     69 }
     70 
     71 void Dij()
     72 {
     73     memset(dis,0x7f,sizeof(dis));
     74     Q.push(mp(0,mp(Id1[1],0))); dis[Id1[1]][0]=0;
     75     while (!Q.empty())
     76     {
     77         int u=Q.top().se.fi,v=Q.top().se.se; Q.pop();
     78         for (int i=head[u];i!=-1;i=edge[i].next)
     79         {
     80             if (dis[edge[i].to][v]>dis[u][v]+edge[i].w)
     81             {
     82                 dis[edge[i].to][v]=dis[u][v]+edge[i].w;
     83                 Q.push(mp(dis[edge[i].to][v],mp(edge[i].to,v)));
     84             }
     85             if (v<k)
     86             {
     87                 if (dis[edge[i].to][v+1]>dis[u][v])
     88                 {
     89                     dis[edge[i].to][v+1]=dis[u][v];
     90                     Q.push(mp(dis[edge[i].to][v+1],mp(edge[i].to,v+1)));
     91                 }
     92             }
     93         }
     94     }
     95 }        
     96 
     97     
     98 int main()
     99 {
    100     Get_Int(Kase);
    101     for (int kase=1;kase<=Kase;kase++)
    102     {
    103         Get_Int(n),Get_Int(m),Get_Int(k);
    104         memset(head,-1,sizeof(head)); Block=0;
    105         Build1(1,1,n); Block++; Build2(1,1,n);
    106         int tot=(Block<<1)+1,a,b,c,d,w;
    107         for (int i=1;i<=m;i++)
    108         {
    109             Get_Int(a),Get_Int(b),Get_Int(c),Get_Int(d),Get_Int(w);
    110             P1.clear(),P2.clear();
    111             Modify1(1,1,n,a,b);
    112             Modify2(1,1,n,c,d);
    113             tot++;
    114             for (int j=0;j<P1.size();j++) Add(P1[j],tot,w);
    115             for (int j=0;j<P2.size();j++) Add(tot,P2[j],0);
    116 
    117 
    118             P1.clear(),P2.clear();
    119             Modify1(1,1,n,c,d);
    120             Modify2(1,1,n,a,b);
    121             tot++;
    122             for (int j=0;j<P1.size();j++) Add(P1[j],tot,w);
    123             for (int j=0;j<P2.size();j++) Add(tot,P2[j],0);
    124         }
    125     }
    126     Dij();
    127     if (dis[Id2[n]][k]==0x7fffffff) puts("CreationAugust is a sb!"); else 
    128         Put_Int(dis[Id2[n]][k]);
    129     return 0;
    130 }
    把标答代码改成Dij系列..
  • 相关阅读:
    一周内签到连续天数求解
    int型动态数组总结
    快速排序总结
    希尔排序总结
    冒泡排序的总结
    桶排序总结
    插入排序的总结
    选择排序的总结
    二分法的五种实现
    安装Yum源
  • 原文地址:https://www.cnblogs.com/yyjxx2010xyu/p/5533846.html
Copyright © 2020-2023  润新知