zoukankan      html  css  js  c++  java
  • 【BZOJ2125】最短路

    题面

    http://darkbzoj.tk/problem/2125

    题解

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<vector>
    #include<cstdlib>
    #include<stack>
    #define ri register int
    #define N 50500
    #define M 105000
    using namespace std;
    
    int tn,n,m,q;
    
    inline int read() {
      int ret=0,f=0; char ch=getchar();
      while (ch<'0' || ch>'9') f|=(ch=='-'),ch=getchar();
      while (ch>='0'&& ch<='9') ret*=10,ret+=ch-'0',ch=getchar();
      return f?-ret:ret;
    }
    
    int ciren[N];
    bool zheng[N];
    
    struct tree {
      vector<int> to[N<<1],len[N<<1];
      void add_edge(int u,int v,int w) {
        to[v].push_back(u); len[v].push_back(w);
      }
      int fa[N<<1],f[N<<1][19],d[N<<1];
      int sL[N<<1];
      void maketree(int x,int ff) {
        f[x][0]=fa[x]=ff;
        for (ri i=1;i<=18;i++) f[x][i]=f[f[x][i-1]][i-1];
        for (ri i=0;i<to[x].size();i++) {
          int y=to[x][i];
          sL[y]=sL[x]+len[x][i]; d[y]=d[x]+1;
          maketree(y,x);
        }
      }
      int lca(int x,int y) {
        if (d[x]<d[y]) swap(x,y);
        for (ri i=18;i>=0;i--) if (d[f[x][i]]>=d[y]) x=f[x][i];
        if (x==y) return x;
        for (ri i=18;i>=0;i--) if (f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
        return fa[x];
      }
      int jump(int x,int y) {
        for (ri i=18;i>=0;i--) if (d[f[x][i]]>d[y]) x=f[x][i];
        return x;
      }
      int query(int x,int y) {
        int t=lca(x,y);
        if (t>tn) {
          int x0=jump(x,t);
          int y0=jump(y,t);
          int ans=sL[x]-sL[x0]+sL[y]-sL[y0];
          if (zheng[x0]!=zheng[y0]) {
            ans+=min(sL[x0]+sL[y0]-2*sL[t],ciren[t]-sL[x0]-sL[y0]+2*sL[t]);
          }
          else {
            ans+=min(abs(sL[x0]-sL[y0]),ciren[t]-abs(sL[x0]-sL[y0]));
          }
          return ans;
        }
        else return sL[x]+sL[y]-2*sL[t];
      }
    } T;
    
    struct graph {
      vector<int> to[N],len[N];
      int dfn[N],low[N],dr[N];
      int cnt;
      stack<int> s;
      void add_edge(int u,int v,int w) {
        to[u].push_back(v); len[u].push_back(w);
        to[v].push_back(u); len[v].push_back(w);
      }
      void tarjan(int x) {
        dfn[x]=low[x]=++cnt;
        s.push(x);
        for (ri i=0;i<to[x].size();i++) {
          int y=to[x][i];
          if (dfn[y]) {
            low[x]=min(low[x],dfn[y]);
          }
          else {
            dr[y]=dr[x]+len[x][i];
            tarjan(y);
            if (low[y]>=dfn[x]) {
              ++n;
              int t=s.top(),cirl=dr[t]-dr[x];
              for (ri j=0;j<to[t].size();j++) if (to[t][j]==x) {cirl+=len[t][j]; break;}
              ciren[n]=cirl;
              do {
                t=s.top(); s.pop();
                if (dr[t]-dr[x]>cirl-dr[t]+dr[x]) zheng[t]=1;
                T.add_edge(t,n,min(dr[t]-dr[x],cirl-dr[t]+dr[x]));
              }
              while (t!=y);
              T.add_edge(n,x,0);
            }
            low[x]=min(low[x],low[y]);
          }
        }
      }
    } G;
    
    int main() {
      int u,v,w;
      tn=n=read(); m=read(); q=read();
      for (ri i=1;i<=m;i++) {
        u=read(); v=read(); w=read();
        G.add_edge(u,v,w);
      }
      G.cnt=0; G.dr[1]=0; G.tarjan(1);
      T.maketree(1,1);
      for (ri i=1;i<=q;i++) {
        int u=read(), v=read();
        printf("%d
    ",T.query(u,v));
      }
      return 0;
    }
  • 相关阅读:
    有关创造力的书籍推荐
    如何做好组织管理?
    EMBA方面的经典自学教材、书籍推荐
    人力资源管理书单推荐
    创新创业类书籍推荐
    企业如何进行组织变革?
    VMS(VELO) tips[转载]
    SAP R/3系统的概念与介绍
    Project Record: RCM Program–Change Delivery Date in VMS Action[转载]
    SQL Server触发器创建、删除、修改、查看示例步骤
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11278555.html
Copyright © 2011-2022 走看看