Codeforces Round #200 (Div. 1)

题目链接

代码链接

A:

串联一个电阻:(a+b)/b

并联一个电阻:a/(a+b)

那么a>=b时连续串联a/b个,a<b时连续并联b/a个,

那么只要修改一下欧几里得就可以了

gcd(a,b):  return b==0 ? 0 : a/b+gcd(b,a%b)

B:

目标状态是‘++...++‘,能发现偶数个‘+‘或者偶数个‘-‘连在一起时,是可以随便转化的(‘++++‘ -> ‘----‘ 或者 ‘----’ -> ‘++++‘),所以一旦有偶数个‘+‘或‘-‘连在一起就可以无视掉了。

所以用一个栈保存还没有被无视的字符,然后O(n)扫一遍串,最后栈空则可行。

C:

问题可以看作是为每个磁头配一个控制范围,然后让每个磁头遍历控制范围的最大时间最小。

最小最大什么的,往二分想就对了。。容易想到,每个磁头的控制范围是不会相交的(相交?看作折返)。

那么就二分答案,从左往右考虑每个磁头,尽可能的使已遍历范围的右端点更远,若能够覆盖所有的位置,则当前答案可行。

D:

容易发现对于任意节点u,只要u子树下有一个空节点,那么u也是空的。然后就可以做了。

把树按照dfs序展开到线段,设1表示empty,0表示filled。

对于操作1,若子树v存在empty节点,则把v的父亲【st[fa],st[fa]】更新成empty。然后把【st[v],ed[v]】更新成filled。

对于操作2,把节点v更新成empty。

对于操作3,询问【st[v],ed[v]】区间内是否有empty节点,没有则表示filled。
E:

Gomory-Hu Tree

论文大意是对于无向容量图,存在一棵树Gomory-Hu Tree,树上两点路径的最小边权等于图上对应两点的MaxFlow。

这棵树的另一个含义是一副n个点的图的任意点对最大流最多只有n-1个取值。

Gomory-Hu Tree需要n-1次MaxFlow来构造。

构造过程:

先有一个点集的集合S: { {1,2,3,...,n-3,n-2,n-1,n} }

step 1:从S中选择一个大小大于1的点集X(若没有则跳向step 6)

step 2:在点集X中选择两个点s,t,直接在原图跑s-t最大流。(这里可能和维基的建图不一样,但是确实是可行的)

step 3:此时点集X分成两个部分:s-t割集。将s-t割集分离,变成两个新的集合A和B。

step 4:将A和B放入S中,并将X从S删除,A和B之间连一条容量为MaxFlow(s,t)的边。

step 5:集合X分离时对于原来连向集合X的边的处理:若点v原属于X,且集合X与另一个集合Y之间的边是通过MaxFlow(v,Y中的点)建立,则Y连向X的边改为连向v现在所属集合的边。转至step 1。

step 6:此时集合S为 { {1},{2},{3},......{n-3},{n-2},{n-1},{n} },把点集合{v}替换成点v。然后就得到点数n,边数n-1的Gomory-Hu Tree。

对于此题的答案,就是Gomory-Hu Tree上的n-1条边权之和。打印路径的话,任选一个起点,然后每次贪心选择边权大的路径走即可。

(渣英语表示硬是看不懂证明过程,泪奔)

Codeforces Round #200 (Div. 1)

上一篇:USACO Healthy Holsteins


下一篇:UML之用例图