HDU3605Escape (maximum number of SAP + state compression optimization points)
EscapeTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission (s): 6239 Accepted Submission (s): 1474
Problem Description 2012 If this is the end of the world how to do? I do not know how. but now scientists have found that some stars, who can live, but some people do not fit to live some of the planet. now scientists want your help, is to determine what all of people can live in these planets.
Input More set of test data, the beginning of each data is n (1 <= n <= 100000), m (1 <= m <= 10) n indicate there n people on the earth, m representatives m planet, planet and people labels are from 0. here are n lines, each line represents a suitable living conditions of people, each row has m digits, the ith digits is 1, said that a person is fit to live in the ith-planet, or is 0 for this person is not suitable for living in the ith planet.
The last line has m digits, the ith digit ai indicates the ith planet can contain ai people most ..
0 <= ai <= 100000
Output Determine whether all people can live up to these stars
If you can output YES, otherwise output NO.
Sample Input
1 1112 21 01 01 1
Sample Output
YESNO
Source 2010 ACM-ICPC Multi-University Training Contest (17) -- Host by ZSTU
Now there are n (<= 100 w) people on the Earth going to m (<= 10) to survive on another planet. Next n rows have m columns in each row, if I is 1, it corresponds to this person who can go to planet I, the planet I can accommodate up to ai individuals (m numbers are given in the last row ). Ask if all people can survive on another planet.
Problem solving: Maximum Flow SAP. As shown in the figure, because of the large number of people, the number of States that can be migrated to a planet is at most 1024, so we can regard each State as a vertex, and the source point is connected to each state by an edge, the number of people whose capacity is in the current state, and the number of people in each state connected to the corresponding planet. Then, each planet is connected to a settlement point, and the side is the number of people that the stars can accommodate.
Another solution is: Multi-match, where humans make x parts and planet make y parts to form a two-part diagram.
The following is the maximum flow SAP solution: Use G ++.
# Include
# Include
# Include
# Define deusing namespace std; # define captype intconst int MAXN = 1030; // the total number of points const int MAXM = 14000; // The total number of sides const int INF = 1 <30; struct EDG {int to, next; captype cap, flow;} edg [MAXM]; int eid, head [MAXN]; int gap [MAXN]; // The number of each distance (or height) Point int dis [MAXN]; // The shortest distance between each point and the end eNode int cur [MAXN]; // cur [u] indicates that starting from the u point can flow through the cur [u] side int pre [MAXN]; inline void init () {eid = 0; memset (head, -1, sizeof (head);} // you can specify three parameters for a directed edge, and four parameters for a undirected edge: inline void addEdg (int u, int v, captype c, captype rc = 0) {edg [eid]. to = v; edg [eid]. next = head [u]; edg [eid]. cap = c; edg [eid]. flow = 0; head [u] = eid ++; edg [eid]. to = u; edg [eid]. next = head [v]; edg [eid]. cap = rc; edg [eid]. flow = 0; head [v] = eid ++;} inline captype maxFlow_sap (int & sNode, int & eNode, int n) {// n is the total number of points including the Source and Sink points. Note memset (gap, 0, sizeof (gap); memset (dis, 0, sizeof (dis); memcpy (cur, head, sizeof (head); pre [sNode] =-1; gap [0] = n; captype ans = 0; // maximum stream int u = sNode, I; while (dis [sNode]
Edg [I]. cap-edg [I]. flow) {Min = edg [I]. cap-edg [I]. flow; inser = I;} I = pre [edg [I ^ 1]. to];} I = pre [u]; while (I! =-1) {edg [I]. flow + = Min; edg [I ^ 1]. flow-= Min; // flow of the backflow edge I = pre [edg [I ^ 1]. to];} ans + = Min; u = edg [inser ^ 1]. to; continue;} bool flag = false; // judge whether int v can flow to adjacent points from the u point; I = cur [u]; while (I! =-1) {v = edg [I]. to; if (edg [I]. cap-edg [I]. flow> 0 & dis [u] = dis [v] + 1) {flag = true; cur [u] = pre [v] = I; break ;} I = edg [I]. next;} if (flag) {u = v; continue;} // if no adjacent vertex of the stream is found, then, the distance (or height) of the starting point u is changed to the minimum distance of the adjacent streamable point + 1 int Mind = n; I = head [u]; while (I! =-1) {if (edg [I]. cap-edg [I]. flow> 0 & Mind> dis [edg [I]. to]) {Mind = dis [edg [I]. to]; cur [u] = I;} I = edg [I]. next;} gap [dis [u] --; if (gap [dis [u] = 0) return ans; // when the distance of dis [u] is absent, it is impossible to find an augmented stream path from the source point. // there is only one distance between the sink point and the current point, then, from the source point to the sink point will inevitably pass through the current point. However, if the current point fails to find the point that can flow, it will inevitably cut off dis [u] = Mind + 1; // If a adjacent vertex that can be streamed is found, the distance between the adjacent vertex is + 1. If not, the distance is n + 1 gap [dis [u] ++; if (u! = SNode) u = edg [pre [u] ^ 1]. to; // return an edge} return ans;} inline void scanf (int & valu) {char ch; while (ch = getchar ()) {if (ch> = '0' & ch <= '9') break;} valu = ch-'0'; while (ch = getchar ()) {if (ch <'0' | ch> '9') break; valu = valu * 10 + ch-'0' ;}} int main () {int n, m, a, s, t, ans, k [1030]; while (scanf ("% d", & n, & m)> 0) {memset (k, 0, sizeof (k); int id = 0, I = 0, j; while (I
0) {if (k [I]> 0) {// status addEdg (s, id, k [I]); j = 0; while (1 <
0? :);}}