先默认读者有基础的网络流以及费用流的知识前置                                                                                                                                                                                                                                                                                                                                                   

1.有上下界无源点汇点的可行流问题:

在本文中指:

原图中没有任何一个点可以凭空产生流量,亦没有任何一个点可以凭空消灭流量;

存在边既有流量上界又有流量下界;

求每条边流量的一组可行解;

满足每个点的入流量等于出流量;

由题意可见本题的图中有环,于是此类问题也被称作循环流;

这里给出的解法是将本题转换为一道普通的有上界最大流问题;

修改本题原图中每条边的流量下界为0,上界为原上界-原下界;

视为该边现在已经拥有了等同于该边流量下界的基础流量了,

然而,由于每条边在原图中的流量下界不同,导致他们现在的基础流量不同;

于是如果再让现在图中每个点出入相等,则表面相等,实则不同;

考虑当现在图中一条边i将x的流量汇入点a,实则汇入x+low[i]的流量(low[i]为i的下界),于是应当有额外一条low[i]的边连入a

考虑当现在图中一条边i将x的流量运出点a,实则运出x+low[i]的流量(low[i]为i的下界),于是应当有额外一条low[i]的边自a连出

由于这些额外的流量在现在图中看来是凭空产生的,所以所有连入原图的边应当自一个额外的源点出发,设为S`

同理,所有连出原图的边应当去往一个额外的汇点,设为T`

然后,跑S`到T`的最大流,希望他可以使附加的边满流;

若附加边满流,则跑出了一组可行流,原图中每条边的可行流是他在现在图中对应边的流量加流量下界

若不满流,则说明无论如何,原图中总会有边达不到下界,于是原图不存在可行流;

注意:存在优化——即可以把所有同起点同终点的边等效为一条流量为加和的边,从S`到a的边的流量可以1:1抵消掉从a到T`的流量

2.有上下界无源点汇点的最小费用流问题:

在本文中指:

在上个问题中的图上加权的费用流问题;

这里给出的解法是直接在上题重构的图中,给每条边符合他来历的权值即可;

由于一定附加边满流才有解,于是可以把附加边贡献的费用视为0上后单独算出加到答案中去;

3.有上下界多个有限源汇点的可行流问题:

在本文中指:

在第一个问题的基础上,有些点必须消灭一定的流量,有些点必须产生一定的流量;

对某些必须产生一定流量x的点,从S`连一条上限为x的附加边;

对某些必须消灭一定流量x的点,向T`连一条上限为x的附加边;

跑最大流,期望附加边满流;

4.问题3的最小费用流版本:

在问题3上附上费用,直接跑费用流即可

5.有上下界一组无限流量源汇点的可行流问题:

在本文中指:

存在边既有流量上界又有流量下界;

存在一个源点S可以随意产生流量,存在一个汇点T可以随便消灭流量

求每条边流量的一组可行解;

满足源汇点之外的每个点入流量等于出流量;

可以看出S的流出等于T的流入;

于是建一条从T到S的流量无限的边,本题的图就属于问题1了;

有趣的是,边T->S的流量可以视作原图中S到T的总流量(因为连上此边后,S,T各自的出入相等)

6.问题5的最小费用流版本:

在问题5上附上费用,直接跑费用流即可

7.问题5的最大流版本:

先跑出问题5的一组可行流;

然而这组可行流并不一定是最大流;

发现一个性质,当我们采用增广路算法求解最大流时,并不会修改源点到汇点路径之外的边的流量大小;

这意味着当我们第一次跑出问题5的一组可行解之后(跑这组可行解,即跑从S`到T`的最大流),

在现在的图上直接跑S到T的最大流,

就能保证

1不会影响被视作原图中边流量下界的边的流量情况——他们依然是满流的;

2图上连的T->S的INF边的退流过程,等价于有一条S->T的边在增广,于是他自动把第一次可行流的答案加入第二次跑出的最大流中;

也就是说,这时跑出来的最大流可以被认为是满足上下界前提下的最大流;

8.问题7的最小费用流版本:

在问题7上附上费用,直接跑费用流即可

 

题目:

bzojP2502

有上下界多个无限源点的费用流问题,好像保证了合法

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int INF=0x3f3f3f3f;
 6 int n,S,T,ansf,answ;
 7 struct ss{
 8     int next,to,f,v,cp;
 9 }e[30010];
10 int first[210],num;
11 int in[210];
12 int que[100010],dis[210],vis[210],flow[210],pre[210],way[210];
13 void bui_(int ,int ,int ,int );
14 void build(int ,int ,int ,int );
15 bool spfa();
16 void EK();
17 int main()
18 {
19     int i,j,k,l,o;
20     scanf("%d",&n);
21     S=n+1,T=S+1;
22     for(i=1;i<=n;i++)
23         bui_(S,i,INF,1);
24     for(i=1;i<=n;i++){
25         scanf("%d",&k),o=0;
26         for(j=1;j<=k;j++){
27             scanf("%d",&l);
28             bui_(i,l,INF,0);
29             in[l]++;o++;
30         }
31         bui_(i,T,o,0);
32     }
33     for(i=1;i<=n;i++)
34         bui_(S,i,in[i],0);
35     while(spfa())
36         EK();
37     printf("%d\n",ansf);
38     return 0;
39 }
40 void bui_(int f,int t,int fi,int vi){
41     build(f,t,fi,vi),e[num].cp=num+1;
42     build(t,f,0,-vi),e[num].cp=num-1;
43 }
44 void build(int f,int t,int fi,int vi){
45     e[++num].next=first[f];
46     e[num].to=t,e[num].f=fi,e[num].v=vi;
47     first[f]=num;
48 }
49 bool spfa(){
50     int i,h=0,t=1;
51     for(i=1;i<=T;i++)vis[i]=0,dis[i]=0x3f3f3f3f;
52     dis[S]=0,flow[S]=INF,que[t]=S;
53     while(h<t){
54         vis[que[++h]]=0;
55         for(i=first[que[h]];i;i=e[i].next)
56             if(e[i].f&&dis[e[i].to]>dis[que[h]]+e[i].v){
57                 dis[e[i].to]=dis[que[h]]+e[i].v;
58                 pre[e[i].to]=que[h],way[e[i].to]=i;
59                 flow[e[i].to]=min(e[i].f,flow[que[h]]);
60                 if(!vis[e[i].to]){
61                     que[++t]=e[i].to;
62                     vis[que[t]]=1;
63                 }
64             }
65     }
66     return dis[T]!=0x3f3f3f3f;
67 }
68 void EK(){
69     int i;
70     ansf+=(flow[T]*dis[T]);
71     for(i=T;i;i=pre[i])
72         if(way[i])
73             e[way[i]].f-=flow[T],e[e[way[i]].cp].f+=flow[T];
74 }
Code1

相关文章:

  • 2021-11-22
  • 2021-05-19
  • 2022-02-17
  • 2021-08-30
  • 2021-08-23
猜你喜欢
  • 2021-06-13
  • 2021-05-24
  • 2022-02-23
  • 2022-02-15
  • 2021-09-21
  • 2021-10-06
  • 2021-06-10
相关资源
相似解决方案