「BalkanOI 2018 Day1」Minmaxtree

每个点都有一个最大和最小权值的限制。

然后每一个权值的限制都必须要取到。

每个点显然可以直接让他取到最大或最小权值。

可以想到每个点匹配一个权值。

不就是一个二分图吗。。。

每个点连向最大和最小权值,然后跑dinic,输出方案,当然本题匈牙利可以跑过。

接下来就是要求每个点的权值限制:可以用LCT直接链标记,也可以离线下来,排序后,依次加入,用一个并查集跳过已经访问过的点。

  1. #include<bits/stdc++.h>
  2. #define rep(q,a,b) for(int q=a,q##_end_=b;q<=q##_end_;++q)
  3. #define dep(q,a,b) for(int q=a,q##_end_=b;q>=q##_end_;--q)
  4. #define mem(a,b) memset(a,b,sizeof a )
  5. #define debug(a) cerr<<#a<<' '<<a<<"___"<<endl
  6. using namespace std;
  7. void in(int &r){
  8. static char c;
  9. r=0;
  10. while(c=getchar(),!isdigit(c));
  11. do r=(r<<1)+(r<<3)+(c^48);
  12. while(c=getchar(),isdigit(c));
  13. }
  14. const int mn=70010;
  15. int head[mn<<1],to[mn<<3],ne[mn<<3],cnt1,W[mn<<3],n;
  16. #define link1(a,b) link_edge1(a,b),link_edge1(b,a)
  17. #define link_edge1(a,b) to[++cnt1]=b,ne[cnt1]=head[a],head[a]=cnt1
  18. #define travel(x) for(int q(head[x]);q;q=ne[q])
  19. struct edge{
  20. int x,y;
  21. }e[mn];
  22. void link(int x,int y);
  23. int cnt;
  24. void pre_dfs(int f,int x){
  25. travel(x)if(to[q]!=f)e[++cnt]={x,to[q]},link(to[q],cnt+n),link(cnt+n,x),pre_dfs(x,to[q]);
  26. }
  27. int son[mn<<1][2],fa[mn<<1];
  28. bool mark[mn<<1];
  29. int Min[mn<<1],Max[mn<<1];
  30. int minv[mn<<1],maxv[mn<<1];
  31. bool noroot(int x){
  32. return x==son[fa[x]][0]||x==son[fa[x]][1];
  33. }
  34. void rotate(int x){
  35. int y=fa[x],z=fa[y],d=x==son[y][1];
  36. if(noroot(y))son[z][y==son[z][1]]=x;
  37. son[y][d]=son[x][!d];
  38. fa[son[x][!d]]=y;
  39. son[x][!d]=y;
  40. fa[x]=z,fa[y]=x;
  41. }
  42. int sta[mn<<1],tp;
  43. void res(int x){
  44. if(!x)return;
  45. swap(son[x][0],son[x][1]);
  46. mark[x]^=1;
  47. }
  48. void min_mark(int x,int v){
  49. if(!x)return;
  50. if(!minv[x])minv[x]=v;
  51. else minv[x]=max(v,minv[x]);
  52. if(!Min[x])Min[x]=v;
  53. else Min[x]=max(Min[x],v);
  54. }
  55. void max_mark(int x,int v){
  56. if(!x)return;
  57. if(!maxv[x])maxv[x]=v;
  58. else maxv[x]=min(v,maxv[x]);
  59. if(!Max[x])Max[x]=v;
  60. else Max[x]=min(Max[x],v);
  61. }
  62. void push_down(int x){
  63. int ls=son[x][0],rs=son[x][1];
  64. if(mark[x]){
  65. res(ls);
  66. res(rs);
  67. mark[x]=0;
  68. }
  69. if(Min[x]){
  70. min_mark(ls,Min[x]);
  71. min_mark(rs,Min[x]);
  72. Min[x]=0;
  73. }
  74. if(Max[x]){
  75. max_mark(ls,Max[x]);
  76. max_mark(rs,Max[x]);
  77. Max[x]=0;
  78. }
  79. }
  80. void splay(int x){
  81. tp=0;
  82. int now=x;
  83. while(noroot(now))sta[++tp]=now,now=fa[now];
  84. sta[++tp]=now;
  85. dep(q,tp,1)push_down(sta[q]);
  86. while(noroot(x)){
  87. int y=fa[x];
  88. if(noroot(y))(x==son[y][1])==(y==son[fa[y]][1])?rotate(y):rotate(x);
  89. rotate(x);
  90. }
  91. }
  92. void access(int x){
  93. for(int y=0;x;y=x,x=fa[x])splay(x),son[x][1]=y;
  94. }
  95. void makeroot(int x){
  96. access(x),splay(x),res(x);
  97. }
  98. void split(int x,int y){
  99. makeroot(x);
  100. access(y),splay(y);
  101. }
  102. void link(int x,int y){
  103. fa[x]=y;
  104. }
  105. int px[mn],ll[mn],rr[mn],hd=0;
  106. void solve(){
  107. int a,b,v,Q;
  108. in(Q);
  109. char c;
  110. while(Q--){
  111. while(c=getchar(),!isalpha(c));
  112. in(a),in(b),in(v);
  113. px[++hd]=v;
  114. split(a,b);
  115. if(c=='M')max_mark(b,v);
  116. else min_mark(b,v);
  117. }
  118. }
  119. void get_min_max(){
  120. sort(px+1,px+hd+1);
  121. rep(q,1,n-1){
  122. splay(n+q);
  123. ll[q]=minv[n+q],rr[q]=maxv[n+q];
  124. }
  125. }
  126. void clear_edge(){
  127. rep(q,1,n)head[q]=0;
  128. cnt1=1;
  129. }
  130. void link_edge(int x,int y,int z){
  131. to[++cnt1]=y,ne[cnt1]=head[x],head[x]=cnt1;
  132. W[cnt1]=z;
  133. }
  134. void link_w(int x,int y,int z){
  135. link_edge(x,y,z);
  136. link_edge(y,x,0);
  137. }
  138. int S,T,tot_node;
  139. void build_graph(){
  140. S=n-1+hd+1;
  141. T=S+1;
  142. tot_node=T;
  143. rep(q,1,n-1)link_w(S,q,1);
  144. rep(q,1,hd)link_w(q+n-1,T,1);
  145. rep(q,1,n-1){
  146. if(ll[q])ll[q]=lower_bound(px+1,px+hd+1,ll[q])-px,link_w(q,ll[q]+n-1,1);
  147. if(rr[q])rr[q]=lower_bound(px+1,px+hd+1,rr[q])-px,link_w(q,rr[q]+n-1,1);
  148. }
  149. }
  150. int depth[mn<<1],cur[mn<<1],que[mn<<1];
  151. bool bfs(){
  152. rep(q,1,tot_node)depth[q]=-1;
  153. int l=0,r=0;
  154. que[++r]=S;
  155. depth[S]=1;
  156. while(l<r){
  157. int now=que[++l];
  158. travel(now)if(depth[to[q]]==-1&&W[q]){
  159. depth[to[q]]=depth[now]+1;
  160. que[++r]=to[q];
  161. if(to[q]==T)return 1;
  162. }
  163. }
  164. return 0;
  165. }
  166. int dfs(int x,int flow){
  167. if(!flow||x==T)return flow;
  168. int used=0;
  169. for(int &q=cur[x];q;q=ne[q])if(depth[to[q]]==depth[x]+1){
  170. int fl=dfs(to[q],min(flow-used,W[q]));
  171. W[q]-=fl;
  172. W[q^1]+=fl;
  173. used+=fl;
  174. if(used==flow)return used;
  175. }
  176. if(!used)depth[x]=-1;
  177. return used;
  178. }
  179. void bipartite_match(){
  180. while(bfs()){
  181. rep(q,1,tot_node)cur[q]=head[q];
  182. dfs(S,1e9);
  183. }
  184. }
  185. bool mk[mn];
  186. const int Rand_lim=1e9;
  187. void out(){
  188. rep(w,1,n-1){
  189. bool ok=0;
  190. travel(w)if(to[q]!=S&&to[q]>=n&&W[q]==0){
  191. printf("%d %d %d\n",e[w].x,e[w].y,px[to[q]-(n-1)]);
  192. mk[to[q]-(n-1)]=1;
  193. ok=1;
  194. }
  195. if(!ok)printf("%d %d %d\n",e[w].x,e[w].y,rr[w]?px[rr[w]]:px[ll[w]]);
  196. }
  197. }
  198. int main(){
  199. freopen("minmaxtree.in","r",stdin);
  200. freopen("minmaxtree.out","w",stdout);
  201. srand(time(NULL));
  202. int a,b;
  203. in(n);
  204. rep(q,2,n)in(a),in(b),link1(a,b);
  205. pre_dfs(0,1);
  206. solve();
  207. get_min_max();
  208. clear_edge();
  209. build_graph();
  210. bipartite_match();
  211. out();
  212. return 0;
  213. }

「BalkanOI 2018 Day1」Minmaxtree的更多相关文章

  1. 「BalkanOI 2018 Day1」Election

    「BalkanOI 2018 Day1」Election 记C为1,T为-1,\(sum[i]\)为\(i\)点的前缀和. 对于询问\([l,r]\),分两步计算答案. 要求所有点的\(sum[i]- ...

  2. 「BalkanOI 2018 Day2」Parentrises

    「BalkanOI 2018 Day2」Parentrises part1 显然可以直接贪心. 右括号记-1,左括号记1. 默认起始全部绿色,不染色. 策略如下: 从左往右扫,如果右括号个数大于左括号 ...

  3. LOJ#2351. 「JOI 2018 Final」毒蛇越狱

    LOJ#2351. 「JOI 2018 Final」毒蛇越狱 https://loj.ac/problem/2351 分析: 首先有\(2^{|?|}\)的暴力非常好做. 观察到\(min(|1|,| ...

  4. 【LOJ】#3032. 「JOISC 2019 Day1」馕

    LOJ#3032. 「JOISC 2019 Day1」馕 处理出每个人把馕切成N段,每一段快乐度相同,我们选择第一个排在最前的人分给他的第一段,然后再在未选取的的人中选一个第二个排在最前的切一下,并把 ...

  5. 【LOJ】#3031. 「JOISC 2019 Day1」聚会

    LOJ#3031. 「JOISC 2019 Day1」聚会 听说随机可过? 我想了很久想了一个不会被卡的做法,建出前\(u - 1\)个点的虚树,然后找第\(u\)个点的插入位置,就是每次找一条最长链 ...

  6. 【LOJ】#3030. 「JOISC 2019 Day1」考试

    LOJ#3030. 「JOISC 2019 Day1」考试 看起来求一个奇怪图形(两条和坐标轴平行的线被切掉了一个角)内包括的点个数 too naive! 首先熟练的转化求不被这个图形包含的个数 -- ...

  7. 「JOISC 2014 Day1」巴士走读

    「JOISC 2014 Day1」巴士走读 将询问离线下来. 从终点出发到起点. 由于在每个点(除了终点)的时间被过来的边固定,因此如果一个点不被新的边更新,是不会发生变化的. 因此可以按照时间顺序, ...

  8. 「JOISC 2014 Day1」 历史研究

    「JOISC 2014 Day1」 历史研究 Solution 子任务2 暴力,用\(cnt\)记录每种权值出现次数. 子任务3 这不是一个尺取吗... 然后用multiset维护当前的区间,动态加, ...

  9. [loj 6496]「雅礼集训 2018 Day1」仙人掌

    传送门 Description 给出一张 \(n\)个点 \(m\)条边的无向连通图,其中每条边至多属于一个简单环,保证没有自环,可能有重边.你需要为其中每条边定向,其中第 \(i\)个点的出度不能超 ...

随机推荐

  1. Elasticsearch核心技术(五):搜索API和搜索运行机制

    本文将从数据存储和搜索的角度简单分析Elasticsearch的搜索运行机制,主要涉及搜索API.搜索机制.存在问题和解决方案. 4.1 Search API Search API允许用户执行一个搜索 ...

  2. JDK中的BitMap实现之BitSet源码分析

    前提 本文主要内容是分析JDK中的BitMap实现之java.util.BitSet的源码实现,基于JDK11编写,其他版本的JDK不一定合适. 文中的图比特低位实际应该是在右边,但是为了提高阅读体验 ...

  3. 高可用k8s集群搭建

    虚拟机选择 Win10 Hyper-V 总体架构 三个master,三个node master的组件 etcd kube-apiserver kube-controller-manager kube- ...

  4. 《MySQL5.7从入门到精通》(高清).PDF,免费无需任何解压密码

    链接:https://pan.baidu.com/s/1nnm5IbExaBhjL6-7qR1Oxw 提取码:vzpx

  5. 分别使用time 和 datetime模块记录当前时间

    工作中经常混淆这两种方法 现记录一下 加深印象 代码如下: >>> import time>>> import datetime>>> ct1 = ...

  6. @RestController和@Controller的关系

    @RestController注解,相当于@Controller+@ResponseBody两个注解的结合

  7. BrowserSync 本地服务器的起用

    最简单粗暴的方法:进入项目根目录,执行命令browser-sync start --server --files "**"     监听所有

  8. 学习Java爬虫文档的学习顺序整理

    1.认识正则表达式(Java语言基础) https://www.toutiao.com/i6796233686455943693/ 2.正则表达式学习之简单手机号和邮箱练习 https://www.t ...

  9. Unity3D开发入门教程(三)——添加启动脚本

    五邑隐侠,本名关健昌,12年游戏生涯. 本教程以 Unity 3D + VS Code + C# + tolua 为例. 一.启动脚本 第一篇 "搭建开发环境",在 "配 ...

  10. 【Java】IntelliJ IDEA 快捷键

    IntelliJ IDEA 快捷键 1. Editing(编辑) 快捷键 介绍 Ctrl +Space 基本代码补全,输入字母按后列出匹配的词组 Ctrl+Shift+Space 智能代码补全,列出与 ...