题意:
有M个机器,N个任务
对第i个任务,需要在[Si,Ei]这段时间内恰有Pi天被process
每天最多有M个机器同时工作
每一天,一个任务若被process,那么它恰占用一个机器。
题解:建图,设一个超级源点S编号为0,超级汇点T编号为1001,编号[1,500]表示任务[1,500],编号[501,100]表示时间[1,500] (为与原题对应,建边时用500作为偏移量)。
每一天最多同时加工M个任务,故每一天向超级汇点连一条容量为M的边 以满足此不等关系。
每个任务最多需要Pi天,那么超级汇点向每个任务连一条容量为Pi的边。
每个任务要在[Si,Ei]中选时间进行process,那么,从任务i向[Si,Ei]中的每一天都分别连一条容量为1的边。
最后,如果跑得的最大流==sigma(Pi),那么就是"Yes"了
#include <bits/stdc++.h> using namespace std; typedef long long LL; namespace FastIO { const static int MX=1e6; bool IOerror=0; char nc() { static char buf[MX],*p1=buf+MX,*pend=buf+MX; if(p1==pend) { p1=buf; pend=buf+fread(buf,1,MX,stdin); if(pend==p1) { IOerror=1; return -1; } } return *p1++; } inline bool blank(char ch) { return ch==' '||ch==' '||ch==' '||ch==' '; } inline int read(int& x) { char ch; while(blank(ch=nc())); if(IOerror) return 0; for(x=ch-'0'; (ch=nc())>='0'&&ch<='9'; x=x*10+ch-'0'); //printf("%d=== ",x); return 1; } } using namespace FastIO; const int N=1005; const int M=1000006; const int INF=0x3f3f3f3f; struct Edge { int to,next; int flow,cap; //根据情况设定变量类型 Edge(){} Edge(int _to,int _next,int _cap,int _flow) { to=_to,next=_next,cap=_cap,flow=_flow; } }; Edge edge[M<<1]; int head[N],tot; int cur[N]; int d[N]; void init() { memset(head,-1,sizeof(head)); tot=0; } inline void addedge(int u,int v,int cap) { edge[tot]=Edge(v,head[u],cap,0); head[u]=tot++; edge[tot]=Edge(u,head[v],0,0); head[v]=tot++; } int bfs(int s,int t) { memset(d,-1,sizeof(d)); queue<int> Q; Q.push(s),d[s]=0; while(!Q.empty()) { int u=Q.front();Q.pop(); for(int i=head[u];~i;i=edge[i].next) { int v=edge[i].to; if(d[v]==-1&&edge[i].cap>edge[i].flow) { d[v]=d[u]+1; if(v==t) return 1; Q.push(v); } } } return ~d[t]; } int dfs(int s,int t,int a) { if(s==t||a==0) return a; int flow=0,df; // for(int& i=cur[s];~i;i=edge[i].next) for(int i=head[s];~i;i=edge[i].next) { int v=edge[i].to; // if(d[v]==d[s]+1 && // (df=dfs(v,t,min(a,edge[i].cap-edge[i].flow))>0)) //这种写法 hdu6214 TLE if(d[v]==d[s]+1&&edge[i].cap>edge[i].flow &&(df=dfs(v,t,min(a,edge[i].cap-edge[i].flow)))>0) { edge[i].flow+=df; edge[i^1].flow-=df; flow+=df; a-=df; if(a==0) break; } } if(flow==0) d[s]=-1; return flow; } int dinic(int s,int t) { int ret=0; while(bfs(s,t)) { // memcpy(cur,head,sizeof(cur)); ret+=dfs(s,t,INF); } return ret; } int main() { int T,kase=0; int s=0,t=1001; read(T); while(T--) { int n,m; // n表示任务总数,m表示点容量 int sum=0; // sum表示实际所需总时间 read(n),read(m); init(); for(int i=1; i<=n; i++) { int l,p,r; read(p),read(l),read(r); sum+=p; addedge(s,i,p); for(int j=l; j<=r; j++) addedge(i,j+500,1); } for(int j=1; j<=500; j++) addedge(j+500,t,m); printf("Case %d: ",++kase); if(dinic(s,t)==sum) puts("Yes"); else puts("No"); puts(""); } }