學習筆記(上下界)

2022-05-25 13:48:09 字數 3656 閱讀 1194

關於上下界網路流學習筆記

無源無匯可行流

首先對於無源無匯,也就是迴圈流,是沒有最大流之說的。

對於每一條邊有乙個流量下界down,和流量上界up,那我們使得此邊流量為up-down,但這樣因為每條邊減少的流量不一樣,所以會導致流量不守恆,

解決方式:因為流入每個點的流量都被剪掉了乙個下界,所以從超級源向每個點連一條流量為流入此點流量下界之和的邊,而從每個點流出的流量也被減掉了乙個下界,所以從每個點向超級匯連一條流量為從此點流出的流量下界之和的邊。但並不是每個圖都有可行流的,再跑完之後,你需要判斷此流量是否可行,只要判斷跑出的最大流是否等於每條邊流量下界之和即可。

另外一種建邊方式,其實每個點向源匯點連邊中只有較大的那一條有用,令sum表示每個點流入下界總量減去流出下界總量,if(sum>0)表示流入的下界的量減去的較多,所以有源點向該點連一條流量為sum的邊,反之則由該點向匯點連一條流量為-sum的邊。這樣建邊的話判斷是否滿流則判斷最大流是否等於所有大於0的sum的和,即判斷所有與源點相連的邊是否滿流即可。

有源有匯可行流

對於乙個有源有匯的模型,要求源點s流出總量等於匯點t的流出總量,且其他邊的流量滿足上下界限制,對於此類問題可以轉換為無源無匯可行流,那麼就要有流量流入源點,有流量流出匯點,注意到源點流出量等於匯點流入量,所以從t向s,連一條流量為inf的邊,相當於把流入t的流量又流回去了,這樣整個圖又變成了乙個無源無匯迴圈流模型,那麼每條邊的可行流流量為t—>s的反向邊的流量+流量下界

有源有匯最大流

對於跑完可行流的殘量網路再次從s到t跑一遍即可,那麼最後的最大流等於第一次的可行流+第二次的最大流。跑之前要刪掉t->s邊上的流量,也要刪掉超級源和超級匯連的所有邊(流量設為0即可)(不然上一次跑的流量會被增廣回去)

有源有匯最小流

與有源有匯最大流相反,我們需要找到滿足上下界的最小流,顯然我們不可能在殘量網路上繼續增廣了,那麼考慮每條邊(u->v)的反向邊,它代表從u->v的流量,那麼我們要讓這個值盡量的小,注意到,當你增廣某條邊時,該邊的flow會減小,而反向邊flow增大,所以我們增廣u->v方向邊,即從t向s跑一遍即可。最小流=可行流-最大流。一樣要記得刪邊。

poj2396

#include#include#include#include#includeusing namespace std;

typedef int sign;

typedef long long ll;

#define for(i,a,b) for(register sign i=(sign)a;i<=(sign)b;++i)

#define fordown(i,a,b) for(register sign i=(sign)a;i>=(sign)b;--i)

const int n=1000+5,m=5e5+5;

bool cmax(sign &a,sign b)

templatet read()

void file()

int n,m,q;

struct edge

e[m];

int head[n<<1],tt,cur[n<<1];

int up[n][n],down[n][n];

const int inf=0x3f3f3f3f;

int s,t,st,ed,tot,jud;

bool err;

void add(int x,int y,int z)

void link(int x,int y,int l1,int l2)

add(st,y,l1);add(x,ed,l1);add(x,y,l2-l1);

}void change(int x,int y,int z,int opt)

void deal(int x,int y,int z,int opt)

}else

}} else

}else

}}void input()

for(i,1,n)

for(j,1,m)

q=read();

while(q--) }

void build()

int dis[n<<1],gap[n<<1];

int dfs(int u,int flow)

} if(!--gap[dis[u]])dis[st]=tot+10;

++gap[++dis[u]];

return flow-res;

}int isap()

} //if(err)

for(i,1,n)for(j,1,m)

printf("%d%c",mp[i][j]+down[i][j],(j==m&&i!=n)?'\n':' '); }}

void init()

int main()

return 0;

}

poj1821

#include#include#include#include#includeusing namespace std;

typedef int sign;

typedef long long ll;

#define for(i,a,b) for(register sign i=(sign)a;i<=(sign)b;++i)

#define fordown(i,a,b) for(register sign i=(sign)a;i>=(sign)b;--i)

const int n=16000+5,k=100+5;

bool cmax(sign &a,sign b)

templatet read()

void file()

int n,k;

int dp[k][n];

struct people

}struct node

;node l[n];

int head,tail;

int ans;

void work()

templatet read()

void file()

struct edge

e[m*n];

int n,m;

int head[n],tt;

int cur[n],dis[n],gap[n];

int sum[n],jud;

void add(int x,int y,int z)

void init()

const int inf=0x3f3f3f3f;

char s1[n],s2[n];

int s,t,st,ed;

int deal(char *ss)

void input()

}void build()

add(t,s,inf);

}void del()

} e[tt].flow=e[tt^1].flow=0;

}int dfs(int u,int flow,int t1,int t2,int tot)

} if(!--gap[dis[u]])dis[t1]=tot;

++gap[++dis[u]];

return flow-res;

}int isap(int t1,int t2,int tot)

return flow;

}void work()

}int main()

return 0;

}

學習筆記 上下界網路流

上下界網路流本質上是給流量網路的每一條便設定了流量上界 c u,v 和下界 b u,v 無源匯上下界可行流 給定無源匯流量網路 g 詢問是否存在一種標定每條邊流量的方式,使得每條邊流量滿足上下界同時每乙個點流量平衡。不妨假設每條邊已經流了 b u,v 的流量,設其為初始流。同時我們在新圖中加入 u ...

上下界網路流學習筆記

一些點,一堆邊,每條邊要滿足流量限制 l,r 先令每條邊流量等於流量下限,得到初始流,初始流可能不滿足流量守恆,再建出殘量網路 上限 下限 求出可能不滿足流量守恆的附加流,使附加流和初始流合併後滿足流量守恆 定義 a i 表示初始流中流入量 流出量 若 a i 0 表示流入量大於流出量,附加量需要流...

Python 學習筆記 上下文

python裡面有個特殊的模組叫做上下文模組,可以和with搭配來實現一些功能。他的執行方式是使用者需要乙個定義乙個生成器的函式 with後面跟這個函式,他會執行yield之前的 然後跳出來,執行with語句下面的 然後再切換回函式,執行finally後面的 比如import contextlib ...