HDU3572Task Schedule (the maximum stream ISAP is faster). The graph creation method is good. hdu3572taskisap
Task ScheduleTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission (s): 5007 Accepted Submission (s): 1636
Problem DescriptionOur geometry princess XMM has stoped her study in computational geometry to concentrate on her newly opened factory. her factory has introduced M new machines in order to process the coming N tasks. for the I-th task, the factory has to start processing it at or after day Si, process it for Pi days, and finish the task before or at day Ei. A machine can only work on one task at a time, and each task can be processed by at most one machine at a time. however, a task can be interrupted and processed on different machines on different days.
Now she wonders whether he has a feasible schedule to finish all the tasks in time. She turns to you for help.
InputOn the first line comes an integer T (T <= 20), indicating the number of test cases.
You are given two integer N (N <= 500) and M (M <= 200) on the first line of each test case. then on each of next N lines are three integers Pi, Si and Ei (1 <= Pi, Si, Ei <= 500), which have the meaning described in the description. it is guaranteed that in a feasible schedule every task that can be finished will be done before or at its end day.
OutputFor each test case, print "Case x:" first, where x is the case number. if there exists a feasible schedule to finish all the tasks, print "Yes", otherwise print "No ".
Print a blank line after each test case.
Sample Input
24 31 3 5 1 1 42 3 73 5 92 22 1 31 2 2
Sample Output
Case 1: Yes Case 2: Yes
Authorallenlowesy
Source2010 ACM-ICPC Multi-University Training Contest (13) -- Host by UESTC
Question: There are M machines and N tasks. Each task must be performed in Si or later, completed in Ei or before, and completed in Pi time units. Each task can work on any (idle) machine. Each machine can only work on one task at a time. Each task can only work on one machine at a time, in addition, the task can be interrupted in half, and the task can be executed on other machines. Q: Can I finish the task within the specified time.
Idea: creating a graph is the key. We can select 0 as the source point, and then connect the source point to each task with an edge. The capacity is the required number of days p, then, each task is connected to the corresponding time point, and the edge capacity is 1. Finally, we need to determine the sink point, you can set the sink point to vt = maxtime + n + 1 (maxtime is the maximum End Time, and n is the number of tasks, then, the edge is connected between each time point and the sink point. The edge capacity is m, which is the number of machines (indicating that up to m machines can process tasks at each time point ), finally, sum (for all pi) =? SAP.
# Include <stdio. h> # include <string. h >#include <queue> using namespace std; # define captype intconst int MAXN = 1010; // the total number of points const int MAXM = 520010; // total number of edges 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 can be considered as a height) Point int dis [MAXN]; // The shortest distance between each node and the endpoint eNode int cur [MAXN]; // cur [u] indicates that the value of void init () can flow through the cur [u] side starting from the u point () {eid = 0; memset (head,-1, sizeof (hea D);} // three parameters with a directed edge and four parameters without a directed edge 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 ++;} // pre-processes the shortest void BFS (int sNode, int eNode) to all vertices {queue <int> q; memset (gap, 0, sizeof (gap); memset (dis,-1, sizeof (dis); gap [0] = 1; dis [eNode] = 0; q. push (eNod E); while (! Q. empty () {int u = q. front (); q. pop (); for (int I = head [u]; I! =-1; I = edg [I]. next) {int v = edg [I]. to; if (dis [v] =-1) {dis [v] = dis [u] + 1; gap [dis [v] ++; q. push (v) ;}}} int S [MAXN]; // path stack, storing the ID number of the edge captype maxFlow_sap (int sNode, int eNode, int n) {BFS (sNode, eNode); // pre-processes the shortest distance from eNode to all vertices. if (dis [sNode] =-1) return 0; // memcpy (cur, head, sizeof (head) from the source node to the inaccessible vertex; int top = 0; // captype ans = 0 on the top of the stack; // maximum stream int u = sNode; while (dis [sNode] <n) {// determines whether the sNode point flows to the next adjacent point if (u = eNode) {// Locate the path captype Min = INF; int inser; for (int I = 0; I <top; I ++) that can add a stream) // find the maximum traffic that can be increased by Min if (Min> edg [S [I]. cap-edg [S [I]. flow) {Min = edg [S [I]. cap-edg [S [I]. flow; inser = I ;}for (int I = 0; I <top; I ++) {edg [S [I]. flow + = Min; edg [S [I] ^ 1]. flow-= Min; // flow of the reflux edge} ans + = Min; top = inser; // you can add another stream from the first edge of the traffic bottleneck in this addstream path, therefore, only the edg [S [top] ^ 1] is cut from the bottleneck. to; // start point of the traffic bottleneck edge continue;} bool flag = false; // you can determine whether the edge can be adjacent from the u point. Point stream int v; for (int I = cur [u]; I! =-1; I = edg [I]. next) {v = edg [I]. to; if (edg [I]. cap-edg [I]. flow> 0 & dis [u] = dis [v] + 1) {flag = true; cur [u] = I; break ;}} if (flag) {S [top ++] = cur [u]; // Add an edge u = v; continue;} // if no adjacent vertex that can flow 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; for (int I = head [u]; I! =-1; I = edg [I]. next) if (edg [I]. cap-edg [I]. flow> 0 & Mind> dis [edg [I]. to]) {Mind = dis [edg [I]. to]; cur [u] = I;} 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 [S [-- top] ^ 1]. to; // return an edge} return ans;} int main () {int T, cas = 0, n, m; scanf ("% d", & T ); while (T --) {scanf ("% d", & n, & m); init (); int maxtime = 0, sump = 0; for (int I = 1; I <= n; I ++) {int P, S, E; scanf ("% d", & P, & S, & E); sump + = P; // total traffic if (E> maxtime) maxtime = E; addEdg (0, I, P ); // The maximum traffic from source point 0 to task I is P for (int j = S; j <= E; j ++) addEdg (I, n + j, 1 ); // task I to Time Point j + n, the maximum edge capacity is 1} int t = maxtime + n + 1; for (int j = 1; j <= Maxtime; j ++) addEdg (j + n, t, m); <span style = "white-space: pre "> </span> // The maximum edge capacity is m printf (" Case % d: % s \ n ", ++ cas, maxFlow_sap (0, t, t) = sump? "Yes": "No ");}}