HDU 3572 Task Schedule
这种题一开始完全想不出模型,题目做多了之后就有感觉了。
对于这道题,求一次最大流,判断是否满流就可以了。
建图:添加超级源点和汇点,对于每个任务,从源点向其连一条边,权值为Pi,因为要保证每个任务做够Pi天,然后把时限区间 si ~ ei 拆成一天一天的,那么该任务对应到一天连权值为1的边,最后,对于某一天,因为有m台机器可以同时工作,那么这一天向汇点连一条边,权值为m,求最大流。
/* HDU 3549 Flow Problem */ #include <vector> #include <list> #include <map> #include <set> #include <queue> #include <deque> #include <stack> #include <algorithm> #include <sstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cstdlib> #include <cstring> #include <queue> using namespace std; #define pii pair<int,int> #define clr(a) memset((a),0,sizeof (a)) #define rep(i,a,b) for(int i=(a);i<=(int)(b);i++) #define per(i,a,b) for(int i=(a);i>=(int)(b);i--) #define inf 1e9 #define eps 1e-6 #define MAXN 1005 #define MAXM 1000005 #define MODN 1000000007 #define debug puts("reach here") #define MP make_pair #define PB push_back #define RI(x) scanf("%d",&x) #define RII(x,y) scanf("%d%d",&x,&y) #define RIII(x,y,z) scanf("%d%d%d",&x,&y,&z) typedef long long LL; struct Edge { int v, w, next; }E[MAXM]; int head[MAXN], NE; int n, m; int gap[MAXN],dis[MAXN],pre[MAXN],cur[MAXN]; void add_edge (int u, int v, int w) { E[NE].v = v; E[NE].w = w; E[NE].next = head[u]; head[u] = NE++; E[NE].v = u; E[NE].w = 0; E[NE].next = head[v]; head[v] = NE++; } inline void checkmin(int &a,int b) {if(a == -1 || a > b)a = b;} int sap(int s,int t) { memset(dis,0,sizeof dis); memset(gap,0,sizeof gap); for(int i=0;i<n;++i) cur[i]=head[i]; int u=pre[s]=s,maxflow=0,aug=-1; gap[0]=n; while(dis[s]<n) { loop:for(int &i=cur[u];i!=-1;i=E[i].next) { int v=E[i].v; if(E[i].w && dis[u]==dis[v]+1) { checkmin(aug,E[i].w); pre[v]=u; u=v; if(v==t) { maxflow+=aug; for(u=pre[u];v!=s;v=u,u=pre[u]) { E[cur[u]].w-=aug; E[cur[u]^1].w+=aug; } aug=-1; } goto loop; } } int mindis=n; for(int i=head[u];i!=-1;i=E[i].next) { int v=E[i].v; if(E[i].w && mindis>dis[v]) { cur[u]=i; mindis=dis[v]; } } if((--gap[dis[u]])==0) break; gap[dis[u]=mindis+1]++; u=pre[u]; } return maxflow; } void init() { NE = 0; memset(head, -1, sizeof head); } int main() { int p, s, e; int t, sum; int cas = 1; scanf("%d", &t); while(t--) { scanf("%d%d", &n, &m); init(); sum = 0; int l = inf, r = -1; rep(i,1,n) { RIII(p, s, e); add_edge(0,i,p); sum += p; l = min(l, s); r = max(r, e); rep(j,s+n,e+n) add_edge(i, j, 1); } int des = 1 + r + n; rep(i,1,r) add_edge(i+n,des,m); n = des + 1; int ans = sap(0, des); printf("Case %d: %s\n\n", cas++, ans == sum ? "Yes" : "No"); } return 0; }