题解思路:先构建一个超级原点0,由原点连向n个任务,每条边的流量为p[i],然后有每个任务连向他们自身的时间点s[i]->e[i],每条边的流量为1,最后再由时间点连向超级终点,每条边流量为m(机器的数量),最后跑一遍最大流,判断满流即可。
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> PII; const int MAXN = 1e4+10; const double EPS = 1e-12; int T,n,m,ss,tt,cas; int p[MAXN],s[MAXN],e[MAXN]; int iter[MAXN],level[MAXN]; struct node{ int to,cap,rev; }; vector<node>G[MAXN]; inline void addedge(int from,int to,int cap){ G[from].push_back(node{to,cap,G[to].size()}); G[to].push_back(node{from,cap,G[from].size()-1}); } inline bool bfs(){ memset(level,0,sizeof(level)); queue<int>q; level[ss]=1; q.push(ss); while(!q.empty()){ int x=q.front();q.pop(); for(int i=0;i<G[x].size();i++){ node &e=G[x][i]; if(e.cap>0&&level[e.to]==0){ level[e.to]=level[x]+1; q.push(e.to); } } } return level[tt]==0 ? 0 : 1; } inline int dfs(int x,int flow){ if(x==tt)return flow; for(int &i=iter[x];i<G[x].size();i++){ node &e=G[x][i]; if(e.cap>0&&level[e.to]>level[x]){ int d=dfs(e.to,min(flow,e.cap)); if(d>0){ e.cap-=d; G[e.to][e.rev].cap+=d; return d; } } } return 0; } int main() { scanf("%d",&T); while(T--){ scanf("%d %d",&n,&m); int sum=0; for(int i=0;i<=2000;i++)G[i].clear(); for(int i=1;i<=n;i++){ scanf("%d %d %d",&p[i],&s[i],&e[i]); sum+=p[i]; } ss=0;tt=2000; for(int i=1;i<=n;i++)addedge(0,i,p[i]); for(int i=1;i<=n;i++) for(int j=s[i];j<=e[i];j++) addedge(i,1000+j,1); for(int i=1;i<=500;i++) addedge(1000+i,2000,m); int ans=0; while(bfs()){ memset(iter,0,sizeof(iter)); int now; while((now=dfs(ss,2e9))) ans+=now; } printf("Case %d: ",++cas); if(ans==sum)printf("Yes "); else printf("No "); printf(" "); } }