图论--网络流题目(持续更新)

poj1273:水题,套模板,求最大流
poj1274:水题,直接套模板
poj3041:
最小点覆盖:选取最小的顶点数来覆盖所有的边,在二分图中最小点覆盖数 = 二分图中的匹配数,采用匈牙利算法.算法模板见hungary.c
DAG的最小路径覆盖是指找最小数目的互相不相交的有向路径,满足DAG的所有顶点都被覆盖.(注意是路径数目)
DAG上的最小路径覆盖 = |V| - 二分图的最大匹配数
证明过程如下:找到了二分图的一个匹配如(X1->X2)那么X1就有后继顶点,所以在有向路径中X1不可能是结尾顶点,通过找到二分图的最大匹配,我们可以找到最多的不可能是结尾顶点的数目,
那么用|V| - 非结尾顶点数,就是结尾顶点数,而每个结尾顶点就对应着一条最小覆盖路径,因为最小覆盖路径是不交差的,所有我们通过找到最大的非结尾顶点数从而找到了最小覆盖路径。
找二分图匹配要运用到拆点,x1拆成x1和x1',同理x2拆成x2和x2'
若x1->x2,则在二分图中x1->x2'
无向图的最小路径覆盖 = |V| - 二分图的最大匹配数 / 2;
网络流的题目要学会拆解点.寻找增广路采用KM算法.


poj1698:可以把每一天看成一个点,然后把每一部电影拆成需要的天数个点,那么就是一个二分匹配,只要有一部电影的某一天找不到匹配的话就说明不能够了。
或者是采用网络流的做法,同样把每一天看成一个点,把每一部电影看成是一个点,添加超级源与超级汇点。
超级源到每部电影的容量为每一部电影需要演的天数,每一天到超级汇的容量是1,表示每天只能选择一部电影。
poj2112:先用floyd构图算出每一个点对之间的最小距离,为了确定最小距离,采用二分枚举的方式,只要距离比枚举大的就不链接边,否则链接边。
然后每一头牛都连接一个机器,容量为1,添加一个超级源点,连接到每一头牛,容量为1。表示一头牛只能够选择一个机器去吃。添加一个超级汇点,每个机器连接到该汇点,容量为C,
表示最多有C头牛可以在该机器上吃。然后做一遍最大流,如果最大流量等于牛的数目的话说明该距离可以满足,则接下去二分即可。
WA的原因,构图的时候应该明确构图,即牛只往机器连接,机器只往超级汇点连接,而不应该将所有的距离满足条件的边连上,因为也会存在牛向牛的流量了。


poj3469:
有两个核,每一个模块需要在某个核上有一定的花费。并且有相互合作的模块,如何相互合作的模块不在同一个核上的话要增加额外的花费。
将模块看成一个点,超级源点到模块连接一条边表示模块a的花费,模块到超级汇点连接一条边,表示模块b的花费。如果两个任务需要合作的话,则在两个模块之间连接一条双向边,表示
模块合作的花费,则对此图做最大流即可。。原因...在想中,今后分成两部分应该想到最大流最小割模型。顺便掌握了dinic算法的非递归实现版本。对于稀疏图和稠密图来说此种算法都能行。
详细见模板。


poj2516:
多次最小费用流,多源点多汇点问题转化成为单源点和单汇点问题。
超级源点到所有汇点的费用是0,表示运输不需要费用。同理多汇点到超级汇点也是一样的。
关于源点到汇点的容量表示成每个汇点的需求量即可,费用就是源点到汇点的费用。多汇点到超级汇点的容量也表示成为需求量。
学会了用spfa来求最小费用流,比bellmanFord更快。


上下界可行流:
没有源点的图:
用上界减去下届,做一遍网络流,但是做了网络流之后流量是不守恒的。假设一条边的上界为upper,下届为lower.
上界减去下届之后为upper - lower的容量。做一遍网络流之后假设流量为K,那么实际流量就为K + lower。
但是不同边的lower不同。所以要弥补容量。假设u->v的流量为g(u->v),v->k的流量为h(v->k)
那么应该有g(u->v) + lower(u->v) = h(v->k) + lower(v->k)
所以h(v->k) - g(u->v) = lower(u->v) - lower(v->k);
所以要满足流量守恒的话,对v点所有的入流量的下界减去v点所有出流量的下界。
如果>0的话说明流出大于流入。要从源点补入lower(u->v) - lower(v->k)的流量。
否则的话说明流入大于流出,要从该点到汇点补一条边的流量。
因为此题涉及多个变量且每个变量有多个要求,所以可以将多个变量看做容量。行和列看作节点。
每个变量相当于一个流量,有上下界的限制,然后进行建图,求解。

你可能感兴趣的:(图论--网络流题目(持续更新))