题面
FJ给他的牛棚的N(2≤N≤50,000)个隔间之间安装了N-1根管道,隔间编号从1到N。所有隔间都被管道连通了。
FJ有K(1≤K≤100,000)条运输牛奶的路线,第i条路线从隔间si运输到隔间ti。一条运输路线会给它的两个端点处的隔间以及中间途径的所有隔间带来一个单位的运输压力,你需要计算压力最大的隔间的压力是多少。
分析
树上点差分模板。
代码
- #include<bits/stdc++.h>
- using namespace std;
- #define N 500050
- int n,m,cnt,ans;
- int c[N],fa[N][20],dep[N],first[N];
- struct email
- {
- int u,v;
- int nxt;
- }e[N*4];
- template<class T>
- inline void read(T &x)
- {
- x=0;int f=1;static char c=getchar();
- while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}
- while(c>='0'&&c<='9'){x=x*10+c-'0',c=getchar();}
- x*=f;
- }
-
- inline void add(int u,int v)
- {
- e[++cnt].nxt=first[u];first[u]=cnt;
- e[cnt].u=u;e[cnt].v=v;
- }
-
- inline void pre(int u,int f)
- {
- for(int i=1;(1<<i)<=dep[u];i++)
- fa[u][i]=fa[fa[u][i-1]][i-1];
- for(int i=first[u];i;i=e[i].nxt)
- {
- int v=e[i].v;
- if(v==f)continue;
- dep[v]=dep[u]+1;
- fa[v][0]=u;
- pre(v,u);
- }
- }
-
- inline int lca(int x,int y)
- {
- if(dep[x]<dep[y])swap(x,y);
- int t=dep[x]-dep[y];
- for(int i=0;(1<<i)<=t;i++)
- if((1<<i)&t)
- x=fa[x][i];
- if(x==y)return x;
- for(int i=19;i>=0;i--)
- if(fa[x][i]!=fa[y][i])
- x=fa[x][i],y=fa[y][i];
- return fa[x][0];
- }
-
- inline void dfs(int u,int f)
- {
- for(int i=first[u];i;i=e[i].nxt)
- {
- int v=e[i].v;
- if(v==f)continue;
- dfs(v,u);
- c[u]+=c[v];
- }
- ans=max(ans,c[u]);
- }
-
- int main()
- {
- read(n),read(m);
- for(int i=1;i<n;i++)
- {
- int u,v;
- read(u),read(v);
- add(u,v);add(v,u);
- }
- pre(1,0);
- for(int i=1;i<=m;i++)
- {
- int s,t;
- read(s),read(t);
- c[s]++,c[t]++,c[lca(s,t)]--,c[fa[lca(s,t)][0]]--;
- }
- dfs(1,0);
- printf("%d\n",ans);
- return 0;
-
- }