Task Schedule
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 5398 Accepted Submission(s): 1742
Problem Description
Our 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.
Now she wonders whether he has a feasible schedule to finish all the tasks in time. She turns to you for help.
Input
On 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.
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.
Output
For 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.
Print a blank line after each test case.
Sample Input
2 4 3 1 3 5 1 1 4 2 3 7 3 5 9 2 2 2 1 3 1 2 2
Sample Output
Case 1: Yes Case 2: Yes
思路:在时间区间建图,其实是在这个区间的每个点都连一条边。
建图方案:超级源点s到每个任务 i 连边,容量为第 i 个任务需要的天数,然后向每个任务的时间区间的所有日期连一条容量为1的边,即从开始到结束都连,然后所有日期到汇点连容量m的边,(因为m台机器同时最多能够做m个任务)。建图过程中记录源点的流量 , 最后再判断是否满流即可。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#define maxn 10000 + 100
#define maxm 1000000 + 10000
#define INF 0x3f3f3f3f
using namespace std;
int n, m;//n个任务,m个机器
struct node {
int u, v, cap, flow, next;
};
node edge[maxm];
int dist[maxn], head[maxn], cur[maxn];
bool vis[maxn];
int cnt, sum ,sect;//sect 为超级汇点, sum记录源点出去的流量
void init(){
cnt = 0;
memset(head, -1, sizeof(head));
}
void add(int u, int v, int w){
edge[cnt] = {u, v, w, 0, head[u]};
head[u] = cnt++;
edge[cnt] = {v, u, 0, 0, head[v]};
head[v] = cnt++;
}
void getmap(){
sum = 0;
int last = 0;
for(int i = 1; i <= n; ++i){
int st, ed, time;
scanf("%d%d%d", &time, &st, &ed);
sum += time;
add(0, i, time);// 0 为超级源点 连接每个任务 容量为完成每个任务的工作时间
last = max(last, ed);
for(int j = st; j <= ed; ++j)
add(i, n + j, 1); // 每个任务连接自己的时间区域,容量为1
}
sect = n + last + 1;
for(int i = 1; i <= sect; ++i)
add(n + i, sect, m);//连接超级汇点,所有的日期连到超级汇点,容量为m
}
bool BFS(int st, int ed){
queue<int>q;
memset(vis, 0 ,sizeof(vis));
memset(dist, -1, sizeof(dist));
q.push(st);
dist[st] = 0;
vis[st] = 1;
while(!q.empty()){
int u = q.front();
q.pop();
for(int i = head[u]; i != -1; i = edge[i].next){
node E = edge[i];
if(!vis[E.v] && E.cap > E.flow){
vis[E.v] = 1;
dist[E.v] = dist[u] + 1;
if(E.v == ed) return true;
q.push(E.v);
}
}
}
return false;
}
int DFS(int x, int ed, int a){
if(a == 0 || x == ed)
return a;
int flow = 0, f;
for(int &i = cur[x]; i != -1; i = edge[i].next){
node &E = edge[i];
if(dist[E.v] == dist[x] + 1 && (f = DFS(E.v, ed, min(a, E.cap - E.flow))) > 0){
E.flow += f;
edge[i ^ 1].flow -= f;
a -= f;
flow += f;
if(a == 0) break;
}
}
return flow;
}
int maxflow(int st, int ed){
int flow = 0;
while(BFS(st, ed)){
memcpy(cur, head, sizeof(head));
flow += DFS(st, ed, INF);
}
return flow;
}
int main (){
int T;
int k = 1;
scanf("%d", &T);
while(T--){
scanf("%d%d", &n, &m);
init();
getmap();
printf("Case %d: ", k++);
if(maxflow(0, sect) == sum) //满流
printf("Yes\n\n");
else
printf("No\n\n");
}
return 0;
}