zoukankan      html  css  js  c++  java
  • zoj3195 联通树上三个点的路径长

    输出有个坑,两个月之前就没对,,今天又被坑了一次

    求联通树上三个点的路径长度,只要求两两点对的最短路径,加起来除以二即可

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    using namespace std;
    #define maxn 50005
    #define DEG 20
    struct Edge{
        int to,next,w;
    }edge[maxn*2];
    int head[maxn],tot;
    inline void addedge(int u,int v,int w){
        edge[tot].to=v;
        edge[tot].next=head[u];
        edge[tot].w=w;
        head[u]=tot++;
    }
    int deg[maxn],depth[maxn],fa[maxn][DEG];
    int flag[maxn];
    void bfs(int root){
        queue<int> que;
        deg[root]=depth[root]=0;
        fa[root][0]=root;
        que.push(root);
        while(!que.empty()){
            int tmp=que.front();que.pop();
            for(int i=1;i<DEG;i++)
                fa[tmp][i]=fa[fa[tmp][i-1]][i-1];
            for(int i=head[tmp];i!=-1;i=edge[i].next){
                int v=edge[i].to;
                if(v==fa[tmp][0]) continue;
                deg[v]=deg[tmp]+1;depth[v]=depth[tmp]+edge[i].w;
                fa[v][0]=tmp;
                que.push(v);
            }
        }
    }
    int query(int u,int v){
        if(deg[u]>deg[v]) swap(u,v);
        int hu=deg[u],hv=deg[v],tu=u,tv=v;
        for(int det=hv-hu,i=0;det;det>>=1,i++)
            if(det&1) tv=fa[tv][i];
        if(tu==tv) return tu;
        for(int i=DEG-1;i>=0;i--){
            if(fa[tu][i]==fa[tv][i])continue;
            tu=fa[tu][i];tv=fa[tv][i];
        }
        return fa[tu][0];
    }
    void init(){
        tot=0;
        memset(head,-1,sizeof head);
        memset(depth,0,sizeof depth);
        memset(deg,0,sizeof deg);
    } 
    int main(){
        int n,q,u,v,w;
        int flagg=0;
        while(~scanf("%d",&n)){
            init();
            for(int i=1;i<n;i++){
                scanf("%d%d%d",&u,&v,&w);
                addedge(u,v,w);addedge(v,u,w);
                flag[v]=1;
            }
            int root;
            for(int i=0;i<n;i++) if(!flag[i]){root=i;break;}
            bfs(root);
            
            if(flagg) putchar('
    ');
            else flagg=1;
            scanf("%d",&q);
            int a,b,c;
            while(q--){
                scanf("%d%d%d",&a,&b,&c);
                int tmp1=query(a,b);
                int dis1=depth[a]+depth[b]-depth[tmp1]*2;
                
                int tmp2=query(b,c);
                int dis2=depth[b]+depth[c]-depth[tmp2]*2;
                
                int tmp3=query(a,c);
                int dis3=depth[a]+depth[c]-depth[tmp3]*2;
                printf("%d
    ",(dis1+dis2+dis3)/2);
            }
        }
    }
  • 相关阅读:
    老毛桃装系统详解
    Eclipse常用快捷键
    oracle数据库查询日期sql语句(范例)、向已经建好的表格中添加一列属性并向该列添加数值、删除某一列的数据(一整列)
    java编程中Properties类的具体作用和使用!
    电感、磁珠和0欧电阻
    AXI总线(转)
    NOR Flash的学习
    allegro中如何添加安装孔(注:在PCB图纸中添加)
    转:一个计算机专业毕业的银行员工工作感受
    Allegro中常见的文件格式
  • 原文地址:https://www.cnblogs.com/zsben991126/p/10017047.html
Copyright © 2011-2022 走看看