HDU 3572 网络流最大流 解题报告

xiaoxiao2021-02-28  82

Task Schedule

Problem Description

Our geometry princess XMM has stoped her study in computational geometry to concentrate on her newly opened factory. Her factory has introduced M new machines in order to process the coming N tasks. For the i-th task, the factory has to start processing it at or after day Si, process it for Pi days, and finish the task before or at day Ei. A machine can only work on one task at a time, and each task can be processed by at most one machine at a time. However, a task can be interrupted and processed on different machines on different days. Now she wonders whether he has a feasible schedule to finish all the tasks in time. She turns to you for help.

Input

On the first line comes an integer T(T<=20), indicating the number of test cases. 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.

Output

For each test case, print “Case x: ” first, where x is the case number. If there exists a feasible schedule to finish all the tasks, print “Yes”, otherwise print “No”. Print a blank line after each test case.

Sample Input 2 4 3 1 3 5 1 1 4 2 3 7 3 5 9

2 2 2 1 3 1 2 2

Sample Output

Case 1: Yes

Case 2: Yes

[解题报告] 我们把每一天时间作为一个节点来用网络流解决该题. 建图的话 ,源点s(编号0), 时间1-500天编号为1到500, N个任务编号为500+1 到500+N, 汇点t(编号501+N). 源点s到每个任务i有边(s, i, Pi) 每一天到汇点有边(j, t, M) 如果任务i能在第j天进行,那么有边(i, j, 1) 注意由于一个任务在一天最多只有1台机器执行,所以该边容量为1,不能为INF或M哦. 最后看最大流是否 == 所有任务所需要的总天数.

(这么ZZ的题调了半天…)

代码如下:

#include<iostream> #include<queue> #include<cstdio> #include<cstring> using namespace std; #define inf 0x3f3f3f3f #define maxv 1001 #define maxe 200101 int nume=0;int head[maxv];int e[maxe][3]; void inline adde(int i,int j,int c) { e[nume][0]=j;e[nume][1]=head[i];head[i]=nume; e[nume++][2]=c; e[nume][0]=i;e[nume][1]=head[j];head[j]=nume; e[nume++][2]=0; } int ss,tt,n,m,all; int vis[maxv];int lev[maxv]; bool bfs() { for(int i=0;i<maxv;i++) vis[i]=lev[i]=0; queue<int>q; q.push(ss); vis[ss]=1; while(!q.empty()) { int cur=q.front(); q.pop(); for(int i=head[cur];i!=-1;i=e[i][1]) { int v=e[i][0]; if(!vis[v]&&e[i][2]>0) { lev[v]=lev[cur]+1; vis[v]=1; q.push(v); } } } return vis[tt]; } int dfs(int u,int minf) { if(u==tt||minf==0)return minf; int sumf=0,f; for(int i=head[u];i!=-1&&minf;i=e[i][1]) { int v=e[i][0]; if(lev[v]==lev[u]+1&&e[i][2]>0) { f=dfs(v,minf<e[i][2]?minf:e[i][2]); e[i][2]-=f;e[i^1][2]+=f; sumf+=f;minf-=f; } } if(!sumf) lev[u]=-1; return sumf; } int Dinic() { int sum=0; while(bfs())sum+=dfs(ss,inf); return sum; } int main() { int T,ct=1; for(scanf("%d",&T);T;--T) { memset(head,-1,sizeof(head)); scanf("%d%d",&n,&m); nume=0,all=0, ss=n+501,tt=n+502; for(int i=1;i<=n;i++) { int P,St,Ed; scanf("%d%d%d",&P,&St,&Ed); all+=P; adde(ss,i,P); for(int j=St;j<=Ed;j++) adde(i,n+j,1); } for(int i=1;i<=500;i++) adde(i+n,tt,m); (Dinic()==all)?printf("Case %d: Yes\n\n",ct++):printf("Case %d: No\n\n",ct++); } return 0; }
转载请注明原文地址: https://www.6miu.com/read-58962.html

最新回复(0)