"Test Instructions" has n tasks, each task must start after Si days (including Si), end at Ei days (including EI), each task lasts for pi, now has M machine, each day can only focus on one of the tasks, each task does not make continuous time. Ask if there is a scenario that will make these n tasks complete successfully
"Type" maximum flow
"Map" set a source point s, each task into a point, s to each task with one edge, the capacity of pi, and then each task to the time Si~ei a capacity of 1, each time to a meeting point with a capacity of the edge of M. This runs the maximum flow can be.
#include <cstdio> #include <cstring> #include <cmath> #include <iostream> #include < algorithm> #include <set> #include <map> #include <stack> #include <vector> #include < queue> #include <string> #include <sstream> #define EPS 1e-9#define for (i,j,k) for (int i=j;i<=k;i++) # Define MAXN 10005#define maxm 1000005#define INF 0x3fffffffusing namespace Std;typedef long Long ll;int I,j,k,n,m,x,y,t,an S,big,cas,num,w,t,u,v,p,s,e,s,f,sum,max_time;bool flag;struct edge{int u,v,weight; int next;} Edge[maxm];int HEAD[MAXN]; /* Head[u] indicates the ordinal of the first adjacency edge of the vertex u, if head[u] =-1, u has no adjacency edge */int current; /* Current number of edges */void Add_edge (int u, int v, int weight) {/* Add forward Edge u->v */edge[current].u = u; EDGE[CURRENT].V = v; Edge[current].weight = weight; Edge[current].next = Head[u]; Head[u] = current++; /* Add reverse Edge v->u */edge[current].u = v; EDGE[CURRENT].V = u; edge[current].weight = 0; Edge[current].next = Head[v]; HEAD[V] = CUrrent++;} int ISAP (int s, int e, int n) {int I,u,v,max_flow,aug,min_lev; /* In the process of searching for an augmented path, Curedge[u] Saves the edges that are currently traversed by the vertex u, looking for the adjacent edge of the vertex u instead of starting from head[u], and then searching from curedge[u], which reduces the number of searches * When the augmented path is found * Curedge saved is an augmented path, such as * 0---Four-->1---six-->2--seven--->3---eight--->4 0,1,2,3,4 is the vertex number, 4678 is the ordinal of the edge * curedge[0 ] = four, curedge[1] = six, ... curedge[3] = 8, curedge[i] that is, save the track you have searched */int CUREDGE[MAXN],PARENT[MAXN],LEVEL[MAXN]; /* Count[l] for the number of vertices that belong to the level L, if there is no vertex at a certain level, * there is a fault, meaning there is no augmented path, this is gap optimization, can end the search process early * Augment[v] represents the maximum allowable traffic from the source point to the vertex V, i.e. The minimum weight of this route */int COUNT[MAXN],AUGMENT[MAXN]; Memset (level) (level,0,sizeof); memset (Count,0,sizeof (count)); At the beginning, each vertex is searched from the first edge for a for (i=0;i<=n;i++) {curedge[i] = Head[i]; } max_flow=0; Augment[s]=inf; Parent[s]=-1; U=s; while (level[s]<n)/* cannot be written level[s] < Max_int */{if (u==e)/* Find an augmented path */{MAX _flow+=augment[e]; aug=augment[E]; Debug ("Find an augmented path, augment =%d\n", "the"); Debug ("%d", e); for (V=parent[e];v!=-1;v=parent[v])/* Traverse path from back to forward */{I=CUREDGE[V]; Debug ("<--%d", V); Edge[i].weight-=aug; Edge[i^1].weight+=aug; /* If I is even, i^1 = i+1, if I is odd, i^1 = i-1 */Augment[edge[i].v]-=aug; if (edge[i].weight==0) u=v; /* You point to the last vertex that is augmented, and continue looking for */}//debug ("\ n") next time; }/* from vertex u down to the adjacency point */For (I=curedge[u];i!=-1;i=edge[i].next)//start with Curedge[u], instead of head[u] from the beginning, Curedge[u] Save is The side I looked for last time * * {v=edge[i].v; if (edge[i].weight>0 && level[u]== (level[v]+1))//* Find an edge and stop */{augment[v]=min (AUGM Ent[u],edge[i].weight); Curedge[u]=i; Parent[v]=u; U=v; Break }} if (I==-1)/* No adjacency point, back to previous point */{ if (--count[level[u]]==0) {//debug ("Vertex%d at level%d fault \ n", U, Level[u]);//GAP optimization Break } Curedge[u]=head[u]; /* All edges of vertex u have been tried, there is no way out, after updating the level of u, and starting from the first edge to find *//Find the level of the smallest adjacency point min_lev=n; for (I=head[u];i!=-1;i=edge[i].next) {if (edge[i].weight>0) { Min_lev=min (Level[edge[i].v],min_lev); }} level[u]=min_lev+1; count[level[u]]++; Debug ("Vertex%d of level=%d\n", U, Level[u]); Debug ("Vertex%d cannot go through, back to%d\n", U, edge[curedge[u]].u); if (u!=s) u=parent[u]; /* Fall back to the previous vertex */}} return max_flow;} int main () {scanf ("%d", &t), for (cas=1;cas<=t;cas++) {memset (head,-1,sizeof (head)), current=0;scanf ("%d%d", &N,&M); S=0;sum=0;max_time=0;for (i=1;i<=n;i++) {scanf ("%d%d%d", &p,&s,&e); Sum+=p;max_time=max (Max_time,e) ; Add_edge (s,i,p);j=s;j<=e;j++) {Add_edge (i,n+j,1);}} F=n+max_time+1;for (i=1;i<=max_time;i++) {Add_edge (n+i,f,m);} if (ISAP (s,f,f) ==sum) printf ("Case%d:yes\n\n", CAs), else printf ("Case%d:no\n\n", CAs);} return 0;}
HDU 3572 Maximum Flow