最近在刷題和各種事情,忘記更新了,最近會把做的題目都更新出來
Task Schedule
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 6018 Accepted Submission(s): 1927
Now she wonders whether he has a feasible schedule to finish all the tasks in time. She turns to you for help.
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.
Print a blank line after each test case.
/************************************************
Desiner:hl
time:2015/11/01
Exe.Time:187MS
Exe.Memory:5776K
題意:有M個機器,有N個任務。每個任務必須在Si 或者以後開始做,在Ei 或者之前完成,
完成任務必須處理Pi 個時間單位。其中,每個任務可以在任意(空閒)機器上工作,每個
機器的同一時刻只能工作一個任務,每個任務在同一時刻只能被一個機器工作,而且任務做
到一半可以打斷,拿去其他機器做。問:能否在規定時間內把任務做完。
題解:源點到每個任務建立一條值爲完成該任務需要的天數的邊
任務到該任務開始到該任務結束的所有天數分別建立一條爲1的邊
天數到匯點建立一條爲題目中機械數量的邊
如果sap算出來的結果是等於他所需要的天數的。說明他們能完成
************************************************/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
using namespace std;
const int MAXN = 100010 ; //點數最大值
const int MAXM = 400010 ; //邊數最大值
const int INF = 0x3f3f3f3f;
int S,V,N,M;
int maxday;
struct Edge{
int to,next,cap,flow;
}edge[MAXM];//注意是MAXM
int tol;
int head[MAXN];
int gap[MAXN],dep[MAXN],pre[MAXN],cur[MAXN];
int aa[555],bb[555],cc[555];
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;
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 build(){
int i,j,k,l,m,n;
init();
for(i=1;i<=N;i++){
addedge(S,i,aa[i]);//源點到每個任務的連線爲PI
for(j=bb[i];j<=cc[i];j++){
addedge(i,N+j,1); //從這個任務到這個任務開始的時間到結束的時間連一條爲1的邊
}
}
for(j=1;j<=maxday;j++){
addedge(j+N,V,M);
}
int orz=sap(S,V,V+1);
return orz;
}
bool solve(int su){
int i,j,k;
int ans;
ans = build();
if(ans==su){
printf("Yes\n");
}
else{
printf("No\n");
}
}
int main(){
int T;
int m,n,q,p;
int i,j,k,a,b,c;
int pisum;
scanf("%d",&T);
for(int cas=1;cas<=T;cas++){
scanf("%d%d",&N,&M);
pisum=maxday=0;
for(i=1;i<=N;i++){
scanf("%d%d%d",&aa[i],&bb[i],&cc[i]);
pisum+=aa[i];
maxday=max(maxday,cc[i]);
}
S=0;
V=N+maxday+1;
printf("Case %d: ",cas);
solve(pisum);
puts("");
}
return 0;
}