Task Schedule
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 10994 Accepted Submission(s): 3343
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
Author
allenlowesy
Source
Recommend
题意:有M台机器,N个任务每个任务完成时间为pi,必须在si-ei这段区间完成,每一天只能用一台机器运转第Ni个任务,即一个任务一天不能被多台机器运行。
网络流跑最大流判满流,每一天看做一个点,建一个源点start,汇点end,start连接每一天的点,权值为M,因为每一天最多有M台机器能运行,对于某一天在一个任务的时间区域类则连接,权值赋为1,因为对于某一个任务一天最多能执行完一个单位的时间,第Ni个任务连接汇点end,权值赋为pi,因为最多能被执行pi个单位时间。
dinic:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
#define XINF INT_MAX
#define INF 0x3F3F3F3F
typedef long long ll;
typedef unsigned long long ull;
#define N 6500
const ll MOD = 998244353;
const int MAXN=6500;//点数的最大值
const int MAXM=205000;//边数的最大值
struct Edge
{
int from, to, cap;
int next;
}edge[MAXM];
int head[N], cnt;
int dep[N];
int n, m;
int s, e, p;
void init()
{
cnt = 0;
memset(head, -1, sizeof(head));
}
void addedge(int u, int v, int cap)
{
edge[cnt].from = u;
edge[cnt].to = v;
edge[cnt].cap = cap;
edge[cnt].next = head[u];
head[u] = cnt++;
edge[cnt].from = v;
edge[cnt].to = u;
edge[cnt].cap = 0;
edge[cnt].next = head[v];
head[v] = cnt++;
}
int BFS(int start,int end)
{
int que[MAXN];
int front,rear;
front=rear=0;
memset(dep,-1,sizeof(dep));
que[rear++]=start;
dep[start]=0;
while(front!=rear)
{
int u=que[front++];
if(front==MAXN)front=0;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(edge[i].cap>0&&dep[v]==-1)
{
dep[v]=dep[u]+1;
que[rear++]=v;
if(rear>=MAXN)rear=0;
if(v==end)return 1;
}
}
}
return 0;
}
int dinic(int start,int end)
{
int res=0;
int top;
int stack[MAXN];//stack为栈,存储当前增广路
int cur[MAXN];//存储当前点的后继
while(BFS(start,end))
{
memcpy(cur,head,sizeof(head));
int u=start;
top=0;
while(1)
{
if(u==end)
{
int min=INF;
int loc;
for(int i=0;i<top;i++)
if(min>edge[stack[i]].cap)
{
min=edge[stack[i]].cap;
loc=i;
}
for(int i=0;i<top;i++)
{
edge[stack[i]].cap-=min;
edge[stack[i]^1].cap+=min;
}
res+=min;
top=loc;
u=edge[stack[top]].from;
}
for(int i=cur[u];i!=-1;cur[u]=i=edge[i].next)
if(edge[i].cap!=0&&dep[u]+1==dep[edge[i].to])
break;
if(cur[u]!=-1)
{
stack[top++]=cur[u];
u=edge[cur[u]].to;
}
else
{
if(top==0)break;
dep[u]=-1;
u=edge[stack[--top]].from;
}
}
}
return res;
}
int main()
{
int T, u, v, w, p, s, e;
scanf("%d", &T);
int Case = 1;
while(T--) {
init();
scanf("%d%d", &n, &m);
int maxn = -INF;
int start = 0, t = n+1;
int sum = 0;
for(int i = 1; i <= n; i++) {
scanf("%d%d%d", &p, &s, &e);
sum += p;
maxn = max(maxn, e);
addedge(i, t, p);
//addedge(start, i, p);
for(int j = s; j <= e; ++j) {
//addedge(start, n+j+1, m);
addedge(n+j+1, i, 1);
// addedge(start, n+j+1, m);
//addedge(i, n+j+1, 1);
// addedge(n+j+1, t, m);
}
}
for(int i = 1; i <= maxn; i++)
addedge(start, i+n+1, m);
int ans = dinic(start, t);
if(ans == sum)
printf("Case %d: Yes\n\n", Case++);
else
printf("Case %d: No\n\n", Case++);
}
return 0;
}
SAP:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
#define XINF INT_MAX
#define INF 0x3F3F3F3F
typedef long long ll;
typedef unsigned long long ull;
const ll MOD = 998244353;
const int MAXN=201000;//点数的最大值
const int MAXM=20000500;//边数的最大值
struct Edge
{
int to, next, cap, flow;
} edge[MAXN*10];
int tol;
int head[MAXN];
int gap[MAXN], dep[MAXN], pre[MAXN], cur[MAXN];
int n, m;
void init()
{
tol = 0;
memset(head, -1, sizeof(head));
}
void addedge(int u, int v, int w, int rw = 0)
{
edge[tol].to = v;edge[tol].cap = w;edge[tol].next = head[u];edge[tol].flow = 0;head[u] = tol++;
edge[tol].to = u;edge[tol].cap = rw;edge[tol].next = head[v];edge[tol].flow = 0;head[v] = tol++;
}
int sap(int start, int end, int N)
{
memset(gap, 0, sizeof(gap));
memset(dep, 0, sizeof(dep));
memcpy(cur, head, sizeof(head));
int u = start;
pre[u] = -1;
gap[0] = N;//N所有的点个数包括源点汇点
int ans = 0;
while(dep[start] < N)
{
if(u == end)
{
int Min = INF;
for(int i = pre[u]; i != -1; i = pre[edge[i^1].to])
if(Min > edge[i].cap - edge[i].flow)
Min = edge[i].cap - edge[i].flow;
for(int i = pre[u]; i != -1; i = pre[ edge[i ^ 1].to ])
{
edge[i].flow += Min;
edge[i^1].flow -= Min;
}
u = start;
ans += Min;
continue;
}
bool flag = false;
int v;
for(int i = cur[u]; i != -1; i = edge[i].next)
{
v = edge[i].to;
if(edge[i].cap - edge[i].flow && dep[v] + 1 == dep[u])
{
flag = true;
cur[u] = pre[v] = i;
break;
}
}
if(flag)
{
u = v;
continue;
}
int Min = N;
for(int i = head[u]; i != -1; i = edge[i].next)
{
if(edge[i].cap - edge[i].flow && dep[edge[i].to] < Min)
{
Min = dep[edge[i].to];
cur[u] = i;
}
}
gap[dep[u]]--;
if(!gap[dep[u]])
return ans;
dep[u] = Min+1;
gap[dep[u]]++;
if(u != start)
u = edge[ pre[u] ^ 1 ].to;
}
return ans;
}
int main()
{
int T, u, v, w, p, s, e;
scanf("%d", &T);
int Case = 1;
while(T--) {
init();
scanf("%d%d", &n, &m);
int maxn = -INF;
int start = 0, t = n+1;
int sum = 0;
for(int i = 1; i <= n; i++) {
scanf("%d%d%d", &p, &s, &e);
sum += p;
maxn = max(maxn, e);
addedge(i, t, p);
//addedge(start, i, p);
for(int j = s; j <= e; ++j) {
//addedge(start, n+j+1, m);
addedge(n+j+1, i, 1);
// addedge(start, n+j+1, m);
//addedge(i, n+j+1, 1);
// addedge(n+j+1, t, m);
}
}
for(int i = 1; i <= maxn; i++)
addedge(start, i+n+1, m);
int ans = sap(start, t, n+maxn+2);
if(ans == sum)
printf("Case %d: Yes\n\n", Case++);
else
printf("Case %d: No\n\n", Case++);
}
return 0;
}