zoukankan      html  css  js  c++  java
  • [题解]luogu_P4886_快递员(点分治

    抄题解

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=100009;
    int n,m;
    struct node{
        int v,nxt,w;
    }e[maxn<<1];
    int head[maxn],cnt;
    inline void add(int u,int v,int w){
        e[++cnt].v=v;e[cnt].w=w;e[cnt].nxt=head[u];head[u]=cnt;
    }
    int siz[maxn],hev[maxn],rt,vis[maxn],sum,mx;
    void find(int x,int fa){
        siz[x]=1;hev[x]=0;
        for(int i=head[x];i;i=e[i].nxt){
            int y=e[i].v;if(y==fa||vis[y])continue;
            find(y,x);
            siz[x]+=siz[y];
            hev[x]=max(hev[x],siz[y]);
        }
        hev[x]=max(hev[x],sum-siz[x]);
        if(hev[x]<mx)rt=x,mx=hev[x];
    }
    int bel[maxn],dep[maxn];//属于哪个子树 
    void dfs(int x,int fa,int rr){
        bel[x]=rr;
        for(int i=head[x];i;i=e[i].nxt){
            int y=e[i].v;if(y==fa)continue;
            dep[y]=dep[x]+e[i].w;
            dfs(y,x,rr);
        }
    }
    int q[maxn],ans=1e9,X[maxn],Y[maxn];
    void solve(int x){
        if(vis[x]){
            printf("%d
    ",ans);
            exit(0);
        }
        vis[x]=1;
        for(int i=head[x];i;i=e[i].nxt){
            int y=e[i].v;
            dep[y]=e[i].w;
            dfs(y,x,y);
        }
        dep[x]=0;
        mx=0;
        q[0]=0;
        int last=0;
        for(int i=1;i<=m;i++)
        if(dep[X[i]]+dep[Y[i]]>mx)mx=dep[X[i]]+dep[Y[i]],q[q[0]=1]=i;
        else if(dep[X[i]]+dep[Y[i]]==mx)q[++q[0]]=i;
        ans=min(ans,mx);
        for(int i=1;i<=q[0];i++){
            if(bel[X[q[i]]]!=bel[Y[q[i]]]){//有点对经过根不能更优 
                printf("%d
    ",ans);exit(0);
            }
            else if(!last)last=bel[X[q[i]]];
            else if(last!=bel[X[q[i]]]){//两个点对不在同一子树,不能更优 
                printf("%d
    ",ans);exit(0);
            }
        }
        mx=1e9;
        sum=siz[last];
        find(last,x);
        solve(rt);
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1,u,w,v;i<n;i++){
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,w);add(v,u,w);
        }
        for(int i=1;i<=m;i++){
            scanf("%d%d",&X[i],&Y[i]);
        }
        mx=1e9;sum=n;find(1,0);
        solve(rt);
    }
  • 相关阅读:
    vs2010 怎样设置文本编辑窗口和解决方案资源管理器同步?
    google浏览器如何导出书签
    C#面试题
    Inkscape tricks
    jupyter-notebook kernel died
    matplotlib 显示中文
    Ubuntu+apt-get update时的源
    vscode设置出错, 无法自动补全
    Ubuntu+vscode打不开
    Ubuntu+Firefox总是打不开网页
  • 原文地址:https://www.cnblogs.com/superminivan/p/11755194.html
Copyright © 2011-2022 走看看