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 也流量守恆,然後就可以轉化為無源匯上下界可行流做啦。這題的建圖很直觀,行列建圖,每行...