1. 程式人生 > >[USACO15DEC]最大流Max Flow(樹鏈剖分,線段樹)

[USACO15DEC]最大流Max Flow(樹鏈剖分,線段樹)

FJ給他的牛棚的N(2≤N≤50,000)個隔間之間安裝了N-1根管道,隔間編號從1到N。所有隔間都被管道連通了。

FJ有K(1≤K≤100,000)條運輸牛奶的路線,第i條路線從隔間si運輸到隔間ti。一條運輸路線會給它的兩個端點處的隔間以及中間途徑的所有隔間帶來一個單位的運輸壓力,你需要計算壓力最大的隔間的壓力是多少。

思路:

比較基礎的樹剖題

對於每條線路

我們維護一個區間最大值的線段樹

通過樹剖實現每個加1的操作

最後讀取總最大值就好

程式碼:

// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#define
rii register int i #define rij register int j using namespace std; int fa[50005],top[50005],size[50005],nid[50005]; int head[50005],n,k,bnt,cnt,sd[50005],wes[50005]; struct ljb{ int to,nxt; }y[100005]; struct tree{ int maxn,lazy; }x[800005]; inline int rd(){ int x=0,f=1;char ch=getchar(); while(!isdigit(ch)) {f=ch=='
-'?0:1;ch=getchar();} while(isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} return f?x:-x; } inline void add(int from,int to) { bnt++; y[bnt].to=to; y[bnt].nxt=head[from]; head[from]=bnt; } inline void pushdown(int bh) { x[bh*2].lazy+=x[bh].lazy; x[bh
*2].maxn+=x[bh].lazy; x[bh*2+1].lazy+=x[bh].lazy; x[bh*2+1].maxn+=x[bh].lazy; x[bh].lazy=0; } void addjl(int l,int r,int nl,int nr,int bh) { if(l<nl) { l=nl; } if(r>nr) { r=nr; } if(l==nl&&r==nr) { x[bh].lazy++; x[bh].maxn++; return; } if(x[bh].lazy!=0) { pushdown(bh); } int mid=(nl+nr)/2; if(l<=mid) { addjl(l,r,nl,mid,bh*2); } if(r>mid) { addjl(l,r,mid+1,nr,bh*2+1); } x[bh].maxn=max(x[bh*2].maxn,x[bh*2+1].maxn); } void dfs1(int wz,int nfa,int nsd) { fa[wz]=nfa; sd[wz]=nsd; size[wz]=1; int maxn=0; for(rii=head[wz];i!=0;i=y[i].nxt) { int to=y[i].to; if(to!=nfa) { dfs1(to,wz,nsd+1); size[wz]+=size[to]; if(size[to]>maxn) { wes[wz]=to; maxn=size[to]; } } } } void dfs2(int wz,int ntop) { cnt++; nid[wz]=cnt; top[wz]=ntop; if(wes[wz]==0) { return; } dfs2(wes[wz],ntop); for(rii=head[wz];i!=0;i=y[i].nxt) { int to=y[i].to; if(wes[wz]!=to&&fa[wz]!=to) { dfs2(to,to); } } } void addlj(int from,int to) { while(top[from]!=top[to]) { if(sd[top[from]]<sd[top[to]]) { swap(from,to); } addjl(nid[top[from]],nid[from],1,n,1); from=fa[top[from]]; } if(sd[from]>sd[to]) { swap(from,to); } addjl(nid[from],nid[to],1,n,1); from=fa[top[from]]; } int main() { // freopen("1.in","r",stdin); // freopen("1.out","w",stdout); n=rd(),k=rd(); for(rii=1;i<n;i++) { int from,to; from=rd(),to=rd(); add(from,to); add(to,from); } dfs1(1,0,0); dfs2(1,1); for(rii=1;i<=k;i++) { int from,to; from=rd(),to=rd(); addlj(from,to); } cout<<x[1].maxn; }