1. 题目链接
2. 题目描述
有 $N$ 个点,$M$ 条边的有向图 $(N\le 100, M\le 5000)$。任意一个点 $i$ 上有$s_i$ 个人,$b_i$ 份食物$(s_i, b_i\le 200)$。
任意一条边 $i$ 有几个属性 $u_i, v_i, c_i, p_i$ $(c_i\le 100, 0\lt p_i\lt 1)$。$u_i, v_i$ 分别表示有向边的两个顶点编号;$c_i$ 表示这条边的最大容量(最多允许几个人通过);点$u_i$ 中的每个人可以沿着这条有向边移动到点 $v_i$,但是除了第一个经过这条边的人不会破坏这条边,剩下的人都会有 $p_i$ 的概率把这条边破坏。图中只要有一条边被破坏了,就认为图被破坏了。
现在需要保证所有人都能拿到一份食物的情况下,求出图被破坏的最小概率。
数据范围:
3. 解题思路
主要思路:拆边 + 对数函数将积性函数转为和性函数 + zkw 最小费用最大流。
首先,对于任意一个点来说,都优先把该点中的食物提供给这个点里面的人。然后可以把 $n$ 个节点分成两类节点,分别是满足 $s_i\gt b_i$ 、 $s_i\lt b_i$。第一类节点中的人移动到第二类节点中去获取食物。
对于边 $i$,设有 $f_i$ 个人经过这条边,那么,这条边不被破坏的概率是 $(1-p_i)^{f_i-1}$,而整个图不被破坏的概率就是
$$\prod_{f_i\gt 0}(1-p_i)^{f_i-1}$$
进行变量代换,令$1-p_i=e^{-w_i}$,即$w_i=\log\frac{1}{1-p_i}$,上式可以由积性函数转为和性函数:
$$\prod_{f_i\gt 0}e{-w_i(f_i-1)}=e{\sum_{f_i\gt 0}-w_i(f_i-1)}$$
最小化图被破坏的概率,那么就等价于最小化$\sum_{f_i\gt 0}w_i(f_i-1)$
然后,将所有的边 $i$ 拆成2条边来看,分别是一条流量为1,费用为0的有向边 和 一条流量为 $c_i-1$,费用为 $w_i$ 的有向边。
然后,很简单地就对最小费用最大流进行建模:
- 首先,创建一个超级源点 $S$ 和一个超级汇点 $T$。
- 然后从源点 $S$ 到所有第一类顶点 $u$ 中连一条流量为$s_u-b_u$,费用为0 的有向边;
- 然后在所有的第二类节点 $v$ 到汇点 $T$ 连一条流量为 $b_v-s_v$,费用为 $0$ 的有向边。
- 将原图中的所有边 $i$ 进行拆边,即:
- $u_i$ 到 $v_i$ 中连一条流量为1,费用为0的有向边
- 从 $u_i$ 到 $v_i$ 连一条流量为$c_i-1$,费用为$w_i=\log\frac{1}{1-p_i}$ 的有向边。
最后跑一下zkw 费用流,得到的费用流中的最小费用 $\mathrm{mincost}=\sum_{f_i\gt 0}w_i(f_i-1)$。
那么,最终的答案为:
$$\begin{align*}
\mathrm{result}&=1-\prod_{f_i\gt 0}e^{-w_i(f_i-1)}\
&=1-e^{\sum_{f_i\gt 0}-w_i(f_i-1)}\
&=1-e^{-\mathrm{mincost}}
\end{align*}$$
4. 参考代码
1 |
|