No 27 POJ2396 上下界網路流

2021-09-25 13:49:48 字數 1751 閱讀 1689

poj炸了,沒測,但zoj1994同一題,可以過。

首先是矩陣,每個行和and列和有約束,找每個單元的值,

自然想到網路流,源點指向每個行節點,權值為行和。

每個列節點指向匯點,權值為列和。

行節點指向列節點的邊為每個單元,初始權值為inf,所求邊流量即為單元的權值。

但是,每個單元也有約束,所有行節點指向列節點的邊也有約束。

自然轉化成上下界網路流。

上 下界

網路流求

法:

\green

上下界網路流

求法:

首先按普通網路流建圖,但是,每條邊儲存兩個權值,下界down和上屆up

然後再新設兩個節點:

超級源點和超級匯點,作用是分離下界權值。

具體做法:

超級源點指向所有原節點,權值為該節點的流入下界和。

所有原節點指向超級匯點,權值為該節點的流出下界和。

所有原邊變為上屆與下界差。

原源點與原匯點新設雙向邊,權值都為inf

在新網路圖上跑超級源點到超級匯點的最大流。

若超級源點發出的所有邊都滿載,則存在乙個滿足所有約束的解。

原 理:

\blue

原理:

所有邊都只有下界值的流量時,不一定是個可行流量,因為對於乙個非源匯節點,流入流出應該是相同的。

新設超級源匯點就是找乙個平衡點,最大流在於要使超級源點滿載,即所有下界滿足。

// shelldawn

// poj2396

// no.27

#include#include#include#include#define mm(x,y) memset(x,y,sizeof(x))

#define inf 0x3f3f3f3f

using namespace std;

#define maxn 250

int s,t,s,t;

int n,m;

// 邊判斷,上下界

int e[maxn][maxn][2];

// 網路流圖

int g[maxn][maxn];

int v[maxn];

void print()}}

if(v[t] > 0) return true;

return false;

}int dfs(int now,int minflow)

}if(flow == 0) v[now] = 0;

return flow;

}int main()else

}else if(a == 0 && b == 0)

}if(!flag)

// 建立網路流

mm(g,0);

// ri 到 cj,淨值

for(int i=0;i}

// 源匯點無窮大

g[s][t] = g[t][s] = inf;

// 對於0~n+m+1所有點 建立超級源點

for(int i=0;i// 計算可行流

int maxflow = 0;

while(bfs(s)) maxflow += dfs(s,inf);

// 判斷滿載

flag = true;

for(int i=0;i// 不滿載

if(!flag)

// 輸出

for(int i=0;i}

}return 0;

}

POJ2396 Budget 上下界網路流

表示弱看了半天才能勉強看懂啊。為什麼有上下界會流量不守恆,可以看這篇文章,裡面有證明。嗯。如果理解了原理的話,這題應該算是乙個入門題了吧。要注意的地方就是,因為給的條件有大於和小於,所以更新low和up的時候用cap 1,cap 1,而不是cap。調了好久才發現的。include include i...

poj2396 Budget 上下界可行流

budget 題意 給定乙個棋盤,給定每一行每一列的和,還有每個點的性質。求乙個合理的棋盤數值放置方式。思路 比較經典的網路流模型,把每一列看成乙個點,每一行看成乙個點,利用上下界可行流的思路建圖就行了,注意這裡由於是嚴格的小於和大於,所以可以利用 x 1,x 1。還有就是這道題的0 0 說的是對整...

POJ2396 Budget 有源匯上下界可行流

好久沒a的這麼舒暢了。第一次寫居然1a辣。part2 有源匯上下界可行流 有源匯上下界可行流就是在多了源點和匯點,這樣導致除了源點和匯點外的其他店都流量守恆,我們可以從 t 向 s連一條容量為無窮大的邊,保證s,t 也流量守恆,然後就可以轉化為無源匯上下界可行流做啦。這題的建圖很直觀,行列建圖,每行...