• BZOJ4227 : 城市


    首先一遍Dijkstra求出S到每个点的最短路,并建出最短路图。

    那么对于一条边,求在这条边不能使用的情况下,到首都S的最短时间会变长的点的数目,等价于求去掉这条边后在最短路图中不能从S出发到达的点的数目。

    对于边x->y,新建一个点z,然后连边x->z->y,这样只需要计算从S到i上必须经过z的点数。

    注意到最短路图是个DAG,我们可以按照拓扑序来建立必经点树:对于一个点x,它在必经点上的父亲为它所有前驱的lca,用倍增即可支持操作。

    时间复杂度$O((n+m)log n)$。

    #include<cstdio>
    typedef long long ll;
    const int N=300010,M=400010,K=19;
    const ll inf=1LL<<60;
    int n,m,S,cnt,i,x,deg[N],g[N],v[M],w[M],nxt[M],ed;
    int size[N],sum[N],id[N],h,t,q[N],dep[N],f[N][K],G[N],NXT[N],V[N];
    ll d[N],ans[N];
    struct E{int x,y,w;}a[M>>1];
    inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
    inline void addedge(int x,int y,int z){v[++ed]=y;w[ed]=z;nxt[ed]=g[x];g[x]=ed;}
    inline void add(int x,int y){deg[y]++;v[++ed]=y;nxt[ed]=g[x];g[x]=ed;}
    inline void addtree(int x,int y){V[++ed]=y;NXT[ed]=G[x];G[x]=ed;}
    struct PI{
      ll x;int y;
      PI(){}
      PI(ll _x,int _y){x=_x,y=_y;}
      inline PI operator+(PI b){return x<=b.x?PI(x,y):b;}
    }val[262145];
    void build(int x,int a,int b){
      val[x]=PI(inf,a);
      if(a==b)return;
      int mid=(a+b)>>1;
      build(x<<1,a,mid),build(x<<1|1,mid+1,b);
    }
    inline void change(int x,int a,int b,int c,ll d){
      if(a==b){val[x].x=d;return;}
      int mid=(a+b)>>1;
      c<=mid?change(x<<1,a,mid,c,d):change(x<<1|1,mid+1,b,c,d);
      val[x]=val[x<<1]+val[x<<1|1];
    }
    inline int lca(int x,int y){
      int i;
      if(dep[x]<dep[y])i=x,x=y,y=i;
      for(i=K-1;~i;i--)if(dep[f[x][i]]>=dep[y])x=f[x][i];
      if(x==y)return x;
      for(i=K-1;~i;i--)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
      return f[x][0];
    }
    void dfs(int x){
      for(int i=G[x];i;i=NXT[i])dfs(V[i]),size[x]+=size[V[i]];
      sum[id[x]]=size[x];
    }
    int main(){
      read(n),read(m);
      for(i=1;i<=m;i++){
        read(a[i].x),read(a[i].y),read(a[i].w);
        addedge(a[i].x,a[i].y,a[i].w);
        addedge(a[i].y,a[i].x,a[i].w);
      }
      read(S);
      for(i=1;i<=n;i++)d[i]=inf;
      build(1,1,n),change(1,1,n,S,d[S]=0);
      while(val[1].x<inf)for(change(1,1,n,x=val[1].y,inf),i=g[x];i;i=nxt[i])if(d[x]+w[i]<d[v[i]])change(1,1,n,v[i],d[v[i]]=d[x]+w[i]);
      for(ed=0,i=1;i<=n;i++)g[i]=0,size[i]=d[i]<inf;
      for(cnt=n,i=1;i<=m;i++){
        if(d[a[i].x]+a[i].w==d[a[i].y])id[++cnt]=i,add(a[i].x,cnt),add(cnt,a[i].y);
        if(d[a[i].y]+a[i].w==d[a[i].x])id[++cnt]=i,add(a[i].y,cnt),add(cnt,a[i].x);
      }
      for(cnt++,i=1;i<cnt;i++)if(!deg[i])add(cnt,i);
      q[h=t=1]=cnt,ed=0;
      while(h<=t){
        x=q[h++];
        if(f[x][0])addtree(f[x][0],x);
        for(dep[x]=dep[f[x][0]]+1,i=1;i<K;i++)f[x][i]=f[f[x][i-1]][i-1];
        for(i=g[x];i;i=nxt[i]){
          if(!f[v[i]][0])f[v[i]][0]=x;else f[v[i]][0]=lca(f[v[i]][0],x);
          if(!(--deg[v[i]]))q[++t]=v[i];
        }
      }
      dfs(cnt);
      for(i=1;i<=m;i++)ans[a[i].x]+=sum[i],ans[a[i].y]+=sum[i];
      for(i=1;i<=n;i++)printf("%lld
    ",ans[i]);
      return 0;
    }
    

      

  • 相关阅读:
    skywalking服务端部署的一些坑
    升级jenkins war包后的问题处理
    无法从cdn上下载节目表问题处理
    jenkins构建状态及参数传递
    vSphereClient克隆虚拟机后网络设置
    升级jenkins war包后的一些想法
    Redis模糊删除Key
    php 0531
    php 0530
    php 0520
  • 原文地址:https://www.cnblogs.com/clrs97/p/4681014.html
Copyright © 2020-2023  润新知