zoukankan      html  css  js  c++  java
  • Greedy Pirate Gym

    对于题意 如果想要获取的硬币数最多,也就是所走的路径和最大,再想一下就是除了t到s这条路外其他的路都是一定能做一遍的(ps 题目给的是一棵树)。

    题目就可以理解为 给定2个点求之间的路径;

    所有边长减去这两点路径就是答案;

    维护一个根节点到其他点的路径长度 d

    维护一个其他节点到根节点路径长度 d1;

    给定s t;

    所以 d1[s]+d[t]-d[lca(s,t)]-d1[lca(s,t)])即为2点之间的路径长度,

    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #include<vector>
    #include<algorithm>
    #include<bits/stdc++.h>
    
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    #define sc(x) scanf("%d",&(x))
    #define inf 0x3f3f3f3f
    
    using namespace std;
    
    const int maxn=1e5+10;
    
    
    struct edge{
        int u,v,w,w1,next;
    }e[maxn*2];
    
    int g[maxn*2],tot=0,d[maxn],d1[maxn];
    int n,dep[maxn];
    
    void make(int u,int v,int w,int w1)
    {
        e[++tot]=(edge){u,v,w,w1,g[u]};
        g[u]=tot;
    }
    
    
    int fa[maxn],fathers[maxn][33];
    
    
    void deep(int u,int v,int de,int dd,int td){
            fa[u]=v;
            fathers[u][0]=v;
            dep[u]=de;
            for(int i=g[u];i>0;i=e[i].next){
                if(e[i].v==v) continue;
                d1[e[i].v]=dd+e[i].w;
                d[e[i].v]=td+e[i].w1;
                deep(e[i].v,u,de+1,dd+e[i].w,td+e[i].w1);
    
            }
    }
    
    void ben(){
        int d=log(n)/log(2)+1;
        for(int k=1;k<=d;k++)
            for(int i=1;i<=n;i++)
            {
                fathers[i][k]=fathers[fathers[i][k-1]][k-1];
            }
    }
    
    int lca(int u,int v){
        int maxn=log(n)/log(2)+1;
        if(dep[u]<dep[v]) swap(u,v);
        int d=dep[u]-dep[v];
        for(int i=0;i<=maxn;i++)
            if((d>>i)&1) u=fathers[u][i];
        if(u==v) return u;
        for(int i=maxn;i>=0;i--)
        {
            if(fathers[u][i]!=fathers[v][i]){
                u=fathers[u][i];
                v=fathers[v][i];
            }
        }
        return fathers[u][0];
    }
    
    int main()
    {
        int t,m;
        sc(t);
        while(t--)
        {
            tot=0;
            mem(g,0);
            sc(n);
            int ans=0;
            for(int i=1;i<n;i++)
            {
                int u,v,w,w1;
                sc(u),sc(v),sc(w),sc(w1);
                ans+=w+w1;
                make(u,v,w,w1);
                make(v,u,w1,w);
            }
            deep(1,-1,0,0,0);
            ben();
            sc(m);
            while(m--)
            {
                int s,t;
                sc(s),sc(t);
                int temp=lca(s,t);
                printf("%d
    ",ans-(d1[s]+d[t]-d[temp]-d1[temp]));
            }
        }
        return 0;
    }
  • 相关阅读:
    docker 镜像相关
    docker相关网站
    docker初识 一
    loadrunner Windows资源指标
    Codeforces Round #368 (Div. 2) Brain's Photos
    CodeForce 589J Cleaner Robot
    CodeForce 677I Lottery
    CodeForce 677D Boulevard
    CodeForce 589B Layer Cake
    Map的遍历
  • 原文地址:https://www.cnblogs.com/minun/p/11270438.html
Copyright © 2011-2022 走看看