题意:用m个机器,处理n个任务,每个任务必须在[si,ei]时间段完成,需要pi天才能完成。每个机器只能处理一个任务, 即每天只能处理m个任务。 题解:可以采用贪心法处理,区间覆盖问题,可以参见刘汝佳的书。 或者采用最大流,建图:把每个任务和每一天看做一个点,增加源点s和汇点t,在s和每个任务之间连一条边,容量为持续 天数;在每一天和t之间连一条边,容量为m;在每个任务和对应天数之间连一条边,容量为1。然后最大流量即为所求。
#include #include #define INF 1<<29; int m,n,ds; int h[1010],vh[1010],flo,flag,cf_path,he[1010],nu; struct ss { int v,ne,s; }st[505000]; int source,sink;//起点 终点 void sap() { nu=0; memset(he,-1,sizeof(he)); memset(st,0,sizeof(st)); memset(vh,0,sizeof(vh)); memset(h,0,sizeof(h)); } void add(int hea,int v,int s) { st[nu].ne=he[hea]; st[nu].v=v; st[nu].s=s; he[hea]=nu++; st[nu].ne=he[v]; st[nu].v=hea; st[nu].s=0; he[v]=nu++; } int dfs(int pos,int cost,int cnt) { if (pos==sink) { return cost; } int j,minh=cnt-1,lv=cost,d; for(j=he[pos];j!=-1;j=st[j].ne) { int v=st[j].v,val=st[j].s; if(val>0) { if (h[v]+1==h[pos]) { if (lv<st[j].s) d=lv; else d=st[j].s; d=dfs(v,d,cnt); st[j].s-=d; st[j^1].s+=d; lv-=d; if (h[source]>=cnt) return cost-lv; if (lv==0) break; } if(h[v]<minh) minh=h[v]; } } if(lv==cost) { --vh[h[pos]]; if(vh[h[pos]]==0) h[source]=cnt; h[pos]=minh+1; ++vh[h[pos]]; } return cost-lv; } int maxflow(int st,int ed,int cnt) { source=st; sink=ed; int ret=0; memset(vh,0,sizeof(vh)); memset(h,0,sizeof(h)); int maxx=10000; vh[st]=cnt; while(h[st]<cnt) { ret+=dfs(st,maxx,cnt); } return ret; } int main() { int a,b; scanf("%d",&a); int cas=0; while(a--) { sap(); scanf("%d%d",&m,&n); ds=2; int i,j,x,y,z,ii,max=0,all=0; int min=INF; for(i=1;i<=m;i++) { ds++; scanf("%d%d%d",&x,&y,&z); all+=x; add(0,i,x); for(ii=y;ii<=z;ii++) {add(i,ii+m,1);} if(z>max) max=z; if(y<min) min=y; } ds+=max-min+1; for(i=1;i<=max;i++) add(i+m,1004,n); if(maxflow(0,1004,ds)==all) printf("Case %d: Yesn",++cas); else printf("Case %d: Non",++cas); printf("n"); } return 0; }