P3128 [USACO15DEC]最大流Max Flow
二次联通门 : P3128 [USACO15DEC]最大流Max Flow
/* luogu P3128 最大流Max Flow 说着最大流。。。 其实跟最大流半毛钱关系没有 是个数据结构题 树剖预处理 线段树维护区间最大值 线段树区间修改 最后查询以1为根节点的子树中的最大值即可。。 */ #include <cstdio> #define Max 50090 inline int max (int a, int b) { return a > b ? a : b; } inline int min (int a, int b) { return a < b ? a : b; } inline int swap (int &a, int &b) { int now = a; a = b; b = now; } void read (int &now) { now = 0; register char word = getchar (); while (word < '0' || word > '9') word = getchar (); while (word <= '9' && word >= '0') { now = now * 10 + word - '0'; word = getchar (); } } class Segment_Tree_Type { private : struct Segment_Tree { int l; int r; int Mid; int Maxn; int Ruri; } tree[Max << 4]; public : void Build (int l, int r, int now) { tree[now].l = l; tree[now].r = r; if (l == r) return ; tree[now].Mid = (l + r) >> 1; Build (l, tree[now].Mid, now << 1); Build (tree[now].Mid + 1, r, now << 1 | 1); } void Change_section (int l, int r, int now) { if (tree[now].l == l && tree[now].r == r) { tree[now].Maxn++; tree[now].Ruri++; return ; } if (tree[now].Ruri) { tree[now << 1].Maxn += tree[now].Ruri; tree[now << 1].Ruri += tree[now].Ruri; tree[now << 1 | 1].Maxn += tree[now].Ruri; tree[now << 1 | 1].Ruri += tree[now].Ruri; tree[now].Ruri = 0; } if (r <= tree[now].Mid) Change_section (l, r, now << 1); else if (l > tree[now].Mid) Change_section (l, r, now << 1 | 1); else { Change_section (l, tree[now].Mid, now << 1); Change_section (tree[now].Mid + 1, r, now << 1 | 1); } tree[now].Maxn = max (tree[now << 1].Maxn, tree[now << 1 | 1].Maxn); } int Query_section_Maxn (int l, int r, int now) { if (tree[now].l == l && tree[now].r == r) return tree[now].Maxn; if (tree[now].Ruri) { tree[now << 1].Maxn += tree[now].Ruri; tree[now << 1].Ruri += tree[now].Ruri; tree[now << 1 | 1].Maxn += tree[now].Ruri; tree[now << 1 | 1].Ruri += tree[now].Ruri; tree[now].Ruri = 0; } tree[now].Maxn = max (tree[now << 1].Maxn, tree[now << 1 | 1].Maxn); if (r <= tree[now].Mid) return Query_section_Maxn (l, r, now << 1); else if (l > tree[now].Mid) return Query_section_Maxn (l, r, now << 1 | 1); else return max (Query_section_Maxn (l, tree[now].Mid, now << 1), Query_section_Maxn (tree[now].Mid + 1, r, now << 1 | 1)); } }; struct Edge_Type { int Edge_Count; int edge_list[Max]; struct Edges { int to; int next; } edge[Max << 2]; void Add_Edge (int from, int to) { Edge_Count++; edge[Edge_Count].to = to; edge[Edge_Count].next = edge_list[from]; edge_list[from] = Edge_Count; Edge_Count++; edge[Edge_Count].to = from; edge[Edge_Count].next = edge_list[to]; edge_list[to] = Edge_Count; } }; Segment_Tree_Type Tree; Edge_Type Graph; class Tree_Chain_Get_Type { private : struct Point_Type { int size; int deep; int father; int up_chain_point; int tree_number; int end; } point[Max]; public : int Count; void Dfs_1 (int now, int father) { int pos = Count++; point[now].father = father; point[now].deep = point[father].deep + 1; for (int i = Graph.edge_list[now]; i; i = Graph.edge[i].next) if (Graph.edge[i].to != father) Dfs_1 (Graph.edge[i].to, now); point[now].size = Count - pos; } void Dfs_2 (int now, int chain) { int pos = 0; point[now].up_chain_point = chain; point[now].tree_number = ++Count; for (int i = Graph.edge_list[now]; i; i = Graph.edge[i].next) if (!point[Graph.edge[i].to].tree_number && point[Graph.edge[i].to].size > point[pos].size) pos = Graph.edge[i].to; if (!pos) { point[now].end = Count; return ; } Dfs_2 (pos, chain); for (int i = Graph.edge_list[now]; i; i = Graph.edge[i].next) if (Graph.edge[i].to != pos && !point[Graph.edge[i].to].tree_number) Dfs_2 (Graph.edge[i].to, Graph.edge[i].to); point[now].end = Count; } void Change (int x, int y) { while (point[x].up_chain_point != point[y].up_chain_point) { if (point[point[x].up_chain_point].deep < point[point[y].up_chain_point].deep) swap (x, y); Tree.Change_section (point[point[x].up_chain_point].tree_number, point[x].tree_number, 1); x = point[point[x].up_chain_point].father; } Tree.Change_section (min (point[x].tree_number, point[y].tree_number), max (point[x].tree_number, point[y].tree_number), 1); } int Get_Start () { return point[1].tree_number; } int Get_End () { return point[1].end; } }; Tree_Chain_Get_Type Make; int M, N; int main (int argc, char *argv[]) { read (N); read (M); int x, y; for (int i = 1; i < N; i++) { read (x); read (y); Graph.Add_Edge (x, y); } Make.Dfs_1 (1, 0); Make.Count = 0; Make.Dfs_2 (1, 1); Tree.Build (1, N, 1); while (M--) { read (x); read (y); Make.Change (x, y); } printf ("%d", Tree.Query_section_Maxn (Make.Get_Start (), Make.Get_End (), 1)); return 0; }
myj 吊打我Orz,xxy 捆起来打我Orz,myl 文化课上天Orz, lrh 姿势水平敲高Orz, hkd 特别胖Orz%%%,cys 智商感人Orz,syl zz专业Orz,我没有学上, 我们未来一片光明