zoukankan      html  css  js  c++  java
  • P4149 [IOI2011]Race(dsu 做法)

    题:https://www.luogu.com.cn/problem/P4149

    题意:找出树上点对距离恰好为k的点对,且点对之间的距离最小,要是不存在输出-1;

    分析:对于每次的dfs的每次u,对于u的每一个孩子v,先计数路径,再把v的子树含的路径更新到桶里

    #include<bits/stdc++.h>
    #include<tr1/unordered_map>
    using namespace std;
    typedef long long ll;
    #define pb push_back
    const int M=2e5+5;
    const int inf=0x3f3f3f3f;
    struct node{
        int v;
        ll w;
    };
    vector<node>g[M];
    unordered_map<ll,ll>mp;
    ll ans,n;
    ll k;
    ll sz[M],deep[M],son[M],vis[M];
    ll dis[M];
    void dfs1(int u,int fa){
        sz[u]=1;
        deep[u]=deep[fa]+1;
        for(auto i:g[u]){
            int v=i.v;
            ll w=i.w;
            if(v!=fa){
                dis[v]=dis[u]+w;
                dfs1(v,u);
                sz[v]+=sz[u];
                if(sz[son[u]]<sz[v])
                    son[u]=v;
            }
        }
    }
    void cal(int u,int fa,int root){
        ll tmp=k-dis[u]+2*dis[root];
        if(mp[tmp]){
            ans=min(ans,mp[tmp]+deep[u]-2*deep[root]);
        }
        for(auto i:g[u]){
            int v=i.v;
            if(v!=fa&&!vis[v])
                cal(v,u,root);
        }
    }
    void update(int u,int fa,int p){
    
        if(p==1){
            if(mp[dis[u]]==0)
                mp[dis[u]]=deep[u];
            else
                mp[dis[u]]=min(mp[dis[u]],deep[u]);
        }
        else
            mp[dis[u]]=0;
        for(auto i:g[u]){
            int v=i.v;
            if(v!=fa&&!vis[v])
                update(v,u,p);
        }
    
    }
    void dfs2(int u,int fa,int sign){
        for(auto i:g[u]){
            int v=i.v;
            if(v!=fa&&v!=son[u])
                dfs2(v,u,0);
        }
        if(son[u])
            dfs2(son[u],u,1),vis[son[u]]=1;
        for(auto i:g[u]){
            int v=i.v;
            if(v!=fa&&!vis[v]){
                cal(v,u,u);
                update(v,u,1);
            }
        }
        if(mp[dis[u]]==0)
            mp[dis[u]]=deep[u];
        else
            mp[dis[u]]=min(mp[dis[u]],deep[u]);
        if(mp[dis[u]+k])
            ans=min(ans,mp[dis[u]+k]-deep[u]);
    
        if(son[u])
            vis[son[u]]=0;
        if(!sign)
            update(u,fa,0),mp[dis[u]]=0;
    
    }
    int main(){
        scanf("%lld%lld",&n,&k);
        for(int i=1;i<n;i++){
            int u,v;
            ll w;
            scanf("%d%d%lld",&u,&v,&w);
            u++,v++;
            g[u].pb(node{v,w});
            g[v].pb(node{u,w});
        }
        dfs1(1,0);
        ans=inf;
        dfs2(1,0,0);
        if(ans==inf)
            puts("-1");
        else
            printf("%d
    ",ans);
        return 0;
    }
    /**
    4 3
    0 1 1
    1 2 2
    1 3 4
    
    
    */
    View Code
  • 相关阅读:
    寒假作业 疫情统计(2/2)
    2020春 软工实践寒假作业(1/2)
    个人作业——软件工程实践总结&个人技术博客
    使用Angular HttpClient与后端通信
    个人作业——软件评测
    结对第二次作业——某次疫情统计可视化的实现
    寒假作业(2/2)
    NSArray
    NSDate和NSDateFormatter
    NSNumber和NSString
  • 原文地址:https://www.cnblogs.com/starve/p/12676238.html
Copyright © 2011-2022 走看看