題目大意
乙個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,所求邊流量即為單元的權值。但是,每個單元也有約束,所有行節點指向列...