Trees slightly solution Difference

A tree difference generally used for statistical and related tree path for a path \ ((S, T) \) , we generally modify their \ (d [S], d [T], d [LCA] \) the value to achieve the purpose, and the answer is usually accomplished through statistical sub-tree, the complexity of the apparently \ (O (the n-) \) .

Example: Maximum Flow

This title is a tree difference of the board title.

Obviously given by difference \ (d [S], d [T] \) plus one, \ (D [the LCA], D [Las [the LCA] [0]] \) minus one, and then the tree is quite Qiuzi to add a node to the tree path.

Much \ (BB \) , put the code directly.

// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
    int f=1,w=0;char x=0;
    while(x<'0'||x>'9') {if(x=='-') f=-1; x=getchar();}
    while(x!=EOF&&x>='0'&&x<='9') {w=(w<<3)+(w<<1)+(x^48);x=getchar();}
    return w*f;
}
const int N=50010;
int n,m,num_edge;
int head[N<<1],d[N],las[N][21],Dep[N];
struct Edge{int next,to;} edge[N<<1];
inline void Add(int from,int to)
{
    edge[++num_edge].next=head[from];
    edge[num_edge].to=to;
    head[from]=num_edge;
}
inline void Dfs(int pos,int fa)
{
    las[pos][0]=fa;Dep[pos]=Dep[fa]+1;
    for(int i=0;i<20;i++) las[pos][i+1]=las[las[pos][i]][i];
    for(int i=head[pos];i;i=edge[i].next)
        if(edge[i].to!=fa) Dfs(edge[i].to,pos);
}
inline int LCA(int u,int v)
{
    if(Dep[u]<Dep[v]) swap(u,v);
    for(int i=20;i>=0;i--) if(Dep[v]<=Dep[u]-(1<<i)) u=las[u][i];
    if(u==v) return u;
    for(int i=20;i>=0;i--) if(las[u][i]!=las[v][i]) u=las[u][i],v=las[v][i];
    return las[u][0];
}
inline void Dfs_For_Ans(int pos,int fa)
{
    for(int i=head[pos];i;i=edge[i].next)
        if(edge[i].to!=fa)
            Dfs_For_Ans(edge[i].to,pos),d[pos]+=d[edge[i].to];
}
int main(){
#ifndef ONLINE_JUDGE
    freopen("A.in","r",stdin);
#endif
    n=read();m=read();
    for(int i=1,u,v;i<n;i++)
        u=read(),v=read(),Add(u,v),Add(v,u);
    Dfs(1,0);
    for(int i=1;i<=m;i++)
    {
        int s=read(),t=read(),lca=LCA(s,t);
        //printf("%d:%d\n",i,lca);
        d[s]++,d[t]++,d[lca]--,d[las[lca][0]]--;
    }
    int ans=-1;Dfs_For_Ans(1,0);
    for(int i=1;i<=n;i++) ans=max(ans,d[i]);
    printf("%d",ans);
}

Example Two: NOIP2015 transport plan

This question a bit mean, the equivalent of the longest shortest path after seeking to modify how much, apparently half, considering how \ (the Check \) .

Two separated \ (S \) after find all greater than \ (S \) by weight of the edge path,

Then determine what you can.

Note that when a differential doing looking weight, i.e. \ (the LCA \) at Save \ (2 \) , \ (S, T \) at the plus \ (1 \) ;

#include<bits/stdc++.h>
using namespace std;
inline int read()
{
    int f=1,w=0;char x=0;
    while(x<'0'||x>'9') {if(x=='-') f=-1; x=getchar();}
    while(x!=EOF&&x>='0'&&x<='9') {w=(w<<3)+(w<<1)+(x^48);x=getchar();}
    return w*f;
}
const int N=300010;
int n,m,num_edge,Tot;
int d[N],Dep[N],Tep[N];
int head[N<<1],las[N][30];
struct Edge{int next,to,dis;} edge[N<<1];
struct Group{int from,to,len,lca;} Pln[N];
inline void Add(int from,int to,int dis)
{
    edge[++num_edge].next=head[from];
    edge[num_edge].dis=dis;
    edge[num_edge].to=to;
    head[from]=num_edge;
}
inline void Dfs(int pos,int fa)
{
    las[pos][0]=fa,Dep[pos]=Dep[fa]+1;
    for(int i=0;i<25;i++) las[pos][i+1]=las[las[pos][i]][i];
    for(int i=head[pos];i;i=edge[i].next)
        if(edge[i].to!=fa)
            d[edge[i].to]=d[pos]+edge[i].dis,Dfs(edge[i].to,pos);
}
inline int LCA(int u,int v)
{
    if(Dep[u]<Dep[v]) swap(u,v);
    for(int i=25;i>=0;i--) if(Dep[u]-(1<<i)>=Dep[v]) u=las[u][i];
    if(u==v) return u;
    for(int i=25;i>=0;i--) if(las[u][i]!=las[v][i]) u=las[u][i],v=las[v][i];
    return las[u][0];
}
inline void Dfs_For_CF(int pos,int fa)
{
    for(int i=head[pos];i;i=edge[i].next)
        if(edge[i].to!=fa)
            Dfs_For_CF(edge[i].to,pos),Tep[pos]+=Tep[edge[i].to];
}
inline bool Check(int s)
{
    int Cnt=0,Max=0;
    memset(Tep,0,sizeof(Tep));
    for(int i=1;i<=m;i++)
        if(Pln[i].len>s)
        {
            Tep[Pln[i].from]++,Tep[Pln[i].to]++;Cnt++;
            Tep[Pln[i].lca]-=2;Max=max(Max,Pln[i].len-s);
        }
    if(!Cnt) return 1;Dfs_For_CF(1,0);
    for(int i=2;i<=n;i++) if(Tep[i]==Cnt&&d[i]-d[las[i][0]]>=Max) return 1;
    return 0;
}
int main(){
#ifndef ONLINE_JUDGE
    freopen("A.in","r",stdin);
#endif
    n=read(),m=read();
    for(int i=1,u,v,d;i<n;i++)
        u=read(),v=read(),d=read(),Add(u,v,d),Add(v,u,d),Tot+=d;
    d[1]=0;Dfs(1,0);
    for(int i=1;i<=m;i++)
    {
        Pln[i].from=read(),Pln[i].to=read();
        Pln[i].lca=LCA(Pln[i].from,Pln[i].to);
        Pln[i].len=d[Pln[i].from]+d[Pln[i].to]-2*d[Pln[i].lca];
    }
    int l=0,r=Tot;
    while(l<r)
    {
        int mid=(l+r)>>1;
        if(Check(mid)) r=mid;
        else l=mid+1;
    }
    printf("%d",l);
}

Guess you like

Origin www.cnblogs.com/wo-shi-zhen-de-cai/p/11361012.html