Maxflow

Maxflow_第1张图片
Maxflow_第2张图片
Maxflow_第3张图片
先lca把这个拉出来,在lca倍增数组上维护f[x][j]这样一个数组表示做了i次全部+1之后对于跳的块整个+1,就是:x ↑ 2 j 2^j 2j。 还要做一个下放操作
Maxflow_第4张图片
把大块全都push到最底下的那个小块,枚举所有的f[x][0]求最大值
有一点点像线段树的区间的修改

#include 
using namespace std;
int pa[100010][22],n,m,s,depth[100010],cnt[100010];
int ans;
vector<int> e[100010];
void dfs(int u,int fa)
{
 depth[u]=depth[fa]+1;
 pa[u][0]=fa;
 for(int i=1;(1<<i)<=depth[u];i++)
  pa[u][i]=pa[pa[u][i-1]][i-1];
 for(int i=0;i<e[u].size();i++)
 {
  int v=e[u][i];
  if(v==fa) 
   continue;
  dfs(v,u);
 }
}
void getans(int u,int fa)
{
 for(int i=0;i<e[u].size();i++)
 {
  int v=e[u][i];
  if(v==fa) 
   continue;
  getans(v,u);
  cnt[u]+=cnt[v];
 }
}
int lca(int x,int y)
{
 if(depth[x]>depth[y])
  swap(x,y);
 for(int i=19;i>=0;i--)
  if(depth[y]>=depth[x]+(1<<i))
   y=pa[y][i];
 if(x==y) 
  return y;
 for(int i=19;i>=0;i--)
  if(pa[x][i]!=pa[y][i])
   x=pa[x][i],y=pa[y][i];
 return pa[y][0];
}
int main(){
 cin>>n>>m;
 for(int i=1;i<n;i++)
 {
  int x,y;
  scanf("%d%d",&x,&y);
  e[x].push_back(y);
  e[y].push_back(x);
 }
 dfs(1,0);
 while(m--)
 {
  int s,t;
  scanf("%d%d",&s,&t);
  cnt[s]++,cnt[t]++;
  cnt[lca(s,t)]--,cnt[pa[lca(s,t)][0]]--;
 }
 getans(1,0);
 for(int i=1;i<=n;i++)
  ans=max(ans,cnt[i]);
 cout<<ans;
 return 0;
}

你可能感兴趣的:(zr,B)