ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

luogu 4886

2019-07-08 21:55:42  阅读:236  来源: 互联网

标签:int luogu maxp 4886 100005 edge siz include


点分治好题

统计距离正常点分治统计即可,我们只需考虑何时达到最优

有两种情况:

第一:代价最大的询问两个端点在不同的两个子树中

因为这种情况下,无论根向那个子树移动都会等价地增加到达另一个端点的代价,因此此时总代价已经达到最小

第二:代价最大的询问有多组,且这些点不在同一棵子树中

同情况一,如果我们把根偏向其中某一棵子树移动的话,那么一定会等价地增大另一端的代价,因此总代价已经达到最小

这样的话直接统计就好了

贴代码:

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;
struct Edge
{
    int nxt;
    int to;
    int val;
}edge[200005];
int q[100005][2];
int siz[100005];
int rt,s;
int head[100005];
int maxp[100005];
int ans=0x3f3f3f3f;
bool vis[100005];
int dis[100005];
int bel[100005];
int ccl[100005];
int col=0,typ=0;
int cnt=1,maxx=0;
int n,m;
void add(int l,int r,int w)
{
    edge[cnt].nxt=head[l];
    edge[cnt].to=r;
    edge[cnt].val=w;
    head[l]=cnt++;
}
void get_rt(int x,int fx)
{
    siz[x]=1,maxp[x]=0;
    for(int i=head[x];i;i=edge[i].nxt)
    {
        int to=edge[i].to;
        if(to==fx||vis[to])continue;
        get_rt(to,x);
        siz[x]+=siz[to];
        maxp[x]=max(maxp[x],siz[to]);
    }
    maxp[x]=max(maxp[x],s-siz[x]);
    if(maxp[x]<maxp[rt])rt=x;
}
void dfs(int x,int fx,int dep)
{
    dis[x]=dep;
    if(!fx)bel[x]=0;
    for(int i=head[x];i;i=edge[i].nxt)
    {
        int to=edge[i].to;
        if(to==fx)continue;
        if(!fx)col++;
        bel[to]=col;
        dfs(to,x,dep+edge[i].val);
    }
}
int calc(int x)
{
    dis[x]=maxx=0,dfs(x,0,0);
    typ++;
    for(int i=1;i<=m;i++)
    {
        ccl[i]=0;
        if(dis[q[i][0]]+dis[q[i][1]]>maxx)maxx=dis[q[i][0]]+dis[q[i][1]],ccl[i]=++typ;
        else if(dis[q[i][0]]+dis[q[i][1]]==maxx)ccl[i]=typ;
    }
    return typ; 
}
void solve(int x)
{
    vis[x]=1;
    int k=calc(x);
    int ori=0;
    for(int i=1;i<=m;i++)
    {
        if((bel[q[i][0]]!=bel[q[i][1]])&&ccl[i]==k){ori=-1;break;}
        else if(ccl[i]==k&&!ori)ori=bel[q[i][0]];
        else if(ccl[i]==k)if(bel[q[i][0]]!=ori){ori=-1;break;}
    }
    ans=min(ans,maxx);
    for(int i=head[x];i;i=edge[i].nxt)
    {
        int to=edge[i].to;
        if(vis[to])continue;
        if(bel[to]==ori)rt=0,s=siz[to],get_rt(to,x),solve(rt);
    }
}
inline int read()
{
    int f=1,x=0;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int main()
{
    n=read(),m=read();
    for(int i=1;i<n;i++)
    {
        int x=read(),y=read(),z=read();
        add(x,y,z),add(y,x,z);
    }
    maxp[0]=0x3f3f3f3f;
    for(int i=1;i<=m;i++)q[i][0]=read(),q[i][1]=read();
    rt=0,s=n,get_rt(1,0),solve(rt);
    printf("%d\n",ans);
    return 0;
}

 

标签:int,luogu,maxp,4886,100005,edge,siz,include
来源: https://www.cnblogs.com/zhangleo/p/11154005.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有