poj 2396 有上下界的網路流

2021-09-08 22:22:51 字數 3246 閱讀 7967

題目大意

乙個mxn的矩陣,給出矩陣中每一行的和sh[1,2...m]以及每一列的數字的和目sv[1,2...n],以及矩陣中的一些元素的範圍限制,比如a[1][2] > 1, a[2][3] < 4, a[3][3] = 10等等,且要求矩陣中的每個元素值非負。求出,是否存在滿足所有給出的限制條件的矩陣,若存在輸出。

題目分析

實現(c++)

#include#include#include#includeusing namespace std;

#define max_node 250

#define max_edge_num 50000

#define infinite 1 << 25

#define min(a, b) ab? a:b

//*************************==== 以下為 尋找最大網路流的 isap演算法 部分 *************************====

struct edge

};edge gedges[max_edge_num];

int gedgecount;

int gflow[max_node][max_node];

int ggap[max_node];

int gdist[max_node];

int ghead[max_node];

int gpre[max_node];

int gpath[max_node];

int ss, tt, sum1, sum2, m, n;

int gsource, gdestination;

void insertedge(int u, int v, int w)

else

} else

}void bfs() }}

int isap(int n)

u = gdestination;

for (e = gpath[u]; u != gsource; e = gpath[u = gpre[u]])

ans += min_flow;

} for (e = ghead[u]; e != -1; e = gedges[e].next)

if (e >= 0)

else

if (--ggap[gdist[u]] == 0) //gap優化

break;

gdist[u] = d + 1; //重標號

++ggap[gdist[u]]; //更新 gap!!

if (u != gsource)

u = gpre[u];//回溯

} }return ans;

}//******************************===以上為 isap 演算法 *************************===

//將圖列印出來,用於debug

void print_graph(int n)

}//儲存 第i行第j列的數字的範圍

struct node;

node gnodes[250][25];

//設定數字的範圍

bool setdatacons(node& node, char op, int val)

if (node.min_val != -1 && node.min_val > val)

node.max_val = node.min_val = val;

} else if (op == '>')

node.min_val = max(node.min_val, val + 1);

} else if (op == '<')

if (node.min_val != -1 && node.min_val >= val)

if (node.max_val != -1)

node.max_val = min(node.max_val, val - 1);

else

node.max_val = val - 1;

} return true;

}//建圖

void buildgraph()

else

}else

else

}} }

}int main()

sum1 += w;

insertedge(ss, i, w);

} insertedge(gsource, tt, sum1);

//輸入的過程中,先插入一些邊 到達 tt的

for (int i = m + 1; i <= m + n; i++)

insertedge(ss, gdestination, sum2);

if (sum1 != sum2)

sum1 = sum2 = (sum1 + sum2);

//設定 矩陣中數字的範圍

scanf("%d", &c);

for (int i = 0; i < c; i++)

if (u == 0)

valid_data = setdatacons(gnodes[i][j],op, val);}}

}else

valid_data = setdatacons(gnodes[i][v], op, val);}}

}else

valid_data = setdatacons(gnodes[u][j], op, val);}}

else

}} if (valid_data == false)

//插入 t-->s的邊,容量無窮大,使得有源匯的網路變為無源匯的網路

insertedge(gdestination, gsource, infinite);

//建圖

buildgraph();

gsource = ss;

gdestination = tt;

// print_graph(n + m + 4);

//找最大流

int ans = isap(n + m + 4);

if (ans != sum1)

//輸出各個邊的流量, 從圖中節點i到節點j的流量,即為 矩陣 中 [i][j-m]的數字的大小

for (int i = 1; i <= m; i++)

printf("\n");

} printf("\n");

} return 0;

}

有源匯上下界可行流 POJ2396

題意 給出乙個n m的矩陣的每行和及每列和,還有一些格仔的限制,求一組合法方案。源點向行,匯點向列,連一條上下界均為和的邊。對於某格的限制,從它所在行向所在列連其上下界的邊。求有源匯上下界可行流即可。具體做法可以從匯點向源點連容量為正無窮的邊,轉成無源匯上下界可行流。然後可以新建超級源匯,對於一條下...

POJ2396 Budget 上下界網路流

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

No 27 POJ2396 上下界網路流

poj炸了,沒測,但zoj1994同一題,可以過。首先是矩陣,每個行和and列和有約束,找每個單元的值,自然想到網路流,源點指向每個行節點,權值為行和。每個列節點指向匯點,權值為列和。行節點指向列節點的邊為每個單元,初始權值為inf,所求邊流量即為單元的權值。但是,每個單元也有約束,所有行節點指向列...