• HDU 2874 Connections between cities


    题解:求树上最短路,所以直接LCA:

    倍增求LCA:

    #include <cstdio>
    int f[10010][18];
    int s[10010],d[10010],from[10010];
    int g[10010],nxt[20010],edv[20010],edw[20010],cnt;
    bool vis[10010];
    int q,a,b,e,n,m,i,j,x,y,tmp;
    void swap(int &a,int &b){int c=a;a=b;b=c;}
    void add(int u,int v,int w){
        edv[++cnt]=v;edw[cnt]=w;
        nxt[cnt]=g[u];g[u]=cnt;
    }
    void dfs(int x,int fa,int fr,int sum){
        from[x]=fr;f[x][0]=fa;
        vis[x]=1;
        d[x]=d[fa]+1;
        s[x]=sum;
        for(int i=g[x];i;i=nxt[i])if(!vis[edv[i]])dfs(edv[i],x,fr,sum+edw[i]);
    }
    int lca(int x,int y){
    	if(x==y)return x;
    	if(d[x]<d[y])swap(x,y);
    	for(int i=17;i>=0;i--)if(d[f[x][i]]>=d[y])x=f[x][i];
    	if(x==y)return x;
    	for(int i=17;i>=0;i--)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
    	return f[x][0];
    }
    int main(){
        while(~scanf("%d%d%d",&n,&m,&q)){
            for(i=0;i<=10000;i++)
             for(j=0;j<18;j++)
               f[i][j]=0;
            for(i=0;i<=n;i++)vis[i]=from[i]=s[i]=d[i]=g[i]=0;
            cnt=0;
            for(i=0;i<m;i++){
                scanf("%d%d%d",&a,&b,&e);
                add(a,b,e);add(b,a,e);
            }
            for(i=1;i<=n;i++)if(!vis[i])dfs(i,0,i,0);
            for(j=1;j<18;j++)
            for(i=1;i<=n;i++)f[i][j]=f[f[i][j-1]][j-1];
            for(i=0;i<q;i++){
                scanf("%d%d",&x,&y);
                if(from[x]!=from[y])puts("Not connected");
                else printf("%d
    ",s[x]+s[y]-2*s[lca(x,y)]);
            }
        }
        return 0;
    }
    

    动态树:

    #include <cstdio>
    #include <cstring>
    #define N 20010
    using namespace std;
    int f[N],son[N][2],sum[N],data[N],a[N];bool rev[N];
    inline void swap(int&a,int&b){int c=a;a=b;b=c;}
    inline bool isroot(int x){return !f[x]||son[f[x]][0]!=x&&son[f[x]][1]!=x;}
    inline void pb(int x){
      if(rev[x]){
        swap(son[x][0],son[x][1]);
        rev[son[x][0]]^=1;rev[son[x][1]]^=1;
        rev[x]=0;
      }
    }
    inline void up(int x){
      sum[x]=data[x]+sum[son[x][0]]+sum[son[x][1]];
    }
    inline void rotate(int x){
      int y=f[x];int w=(son[y][1]==x);
      son[y][w]=son[x][w^1];
      if(son[x][w^1])f[son[x][w^1]]=y;
      if(f[y]){
        int z=f[y];
        if(son[z][0]==y)son[z][0]=x;
        if(son[z][1]==y)son[z][1]=x;
      }
      f[x]=f[y];son[x][w^1]=y;f[y]=x;up(y);
    }
    inline void splay(int x){
      int s=1,i=x,y;a[1]=i;
      while(!isroot(i))a[++s]=i=f[i];
      while(s)pb(a[s--]);
      while(!isroot(x)){
        y=f[x];
        if(!isroot(y)){if((son[f[y]][0]==y)^(son[y][0]==x))rotate(x);else rotate(y);}
        rotate(x);
      }
      up(x);
    }
    inline void access(int x){
      for(int y=0;x;y=x,x=f[x]){
        splay(x);
        son[x][1]=y;
        up(x);
      }
    }
    inline int root(int x){
      access(x);
      splay(x);
      while(son[x][0])x=son[x][0];
      return x;
    }
    inline void makeroot(int x){
      access(x);
      splay(x);
      rev[x]^=1;
    }
    inline void link(int x,int y){
      makeroot(x);
      f[x]=y;
      access(x);
    }
    inline int getsum(int x,int y){
      makeroot(x);
      access(y);
      splay(x);
      return sum[x];
    }
    inline void read(int&a){
      char ch;while(!((ch=getchar())>='0')&&(ch<='9'));
      a=ch-'0';while(((ch=getchar())>='0')&&(ch<='9'))a*=10,a+=ch-'0';
    }
    int n,m,x,y,c,q;
    inline void solve(){
      memset(f,0,sizeof f);
      memset(son,0,sizeof son);
      memset(sum,0,sizeof sum);
      memset(data,0,sizeof data);
      memset(rev,0,sizeof rev);
      read(m);read(q);
      for(int i=1;i<=m;i++){
        read(x);read(y);read(c);
        sum[n+i]=data[n+i]=c;
        link(x,n+i);link(n+i,y);
      }
      while(q--){
        read(x);read(y);
        if(root(x)!=root(y))puts("Not connected");
        else printf("%d
    ",getsum(x,y));
      }
    }
    int main(){
      while(~scanf("%d",&n))solve();
      return 0;
    }
    
  • 相关阅读:
    (40)C#windows服务控制
    (6)C#事务处理
    (1)sqlite基础
    bzoj 2456 mode
    bzoj 2763 [JLOI2011]飞行路线
    bzoj1010[HNOI2008] 玩具装箱toy
    bzoj1034 [ZJOI2008]泡泡堂BNB
    [bzoj1059] [ZJOI2007] 矩阵游戏 (二分图匹配)
    [bzoj1066] [SCOI2007] 蜥蜴
    bzoj1072 [SCOI2007]排列perm
  • 原文地址:https://www.cnblogs.com/forever97/p/3576853.html
Copyright © 2020-2023  润新知