hdu3572 Task Schedule (最大流+构图思维)

来源:互联网 发布:软件定义存储解决方案 编辑:程序博客网 时间:2024/05/16 14:27

题目链接:

http://acm.split.hdu.edu.cn/showproblem.php?pid=3572

题目大意:

有N个任务,每个任务只能在其对应的S天到E天执行,需要的时间为P,不要求连续执行,但是每个任务每天只能有一台机器工作。

有M台机器,每个机器同一时间只能执行一项任务,每项任务同一时间只能被一台机器执行。问是否存在一种时间安排使任务都能被完成。

题目思路:

分析题目最多500的单位时间,所以我们设源点为0,汇点为1000,那么就开始建图了,将任务看作点Ci,那么我们建立E(0,Ci,Pi),任务又与单位时间有关系,再某个任务的时间内建立E(Ci,t,1)单位时间内只允许1个机器。最后,再将单位时间汇入汇点,因为每个单位时间最多允许M台机器同时在线,那么我们建立E(t,1000,M)。

建立好图后,求出最大流,判断与题目中所得要求时间和的大小进行比较,最后进行判断。

学到的东西:

构图方法。画图分析。

代码:

#include<bits/stdc++.h>  using namespace std;  #define maxn 1100  #define INF 0xfffffff  int deep[maxn],N,M,cnt,head[maxn];  int s,t;  struct Edge  {      int v,cap;      int next;  }edge[maxn*maxn];  int bfs()  {      memset(deep,-1,sizeof(deep));      queue<int>q;      q.push(s);      deep[s]=0;      while(!q.empty())      {          int now=q.front();          q.pop();          for(int nex=head[now];nex!=-1;nex=edge[nex].next)          {              if(deep[edge[nex].v]==-1&&edge[nex].cap>0)              {                  deep[edge[nex].v]=deep[now]+1;                  q.push(edge[nex].v);              }          }      }      if(deep[t]==-1) return 0;      return 1;  }  int Min(int a,int b)  {      return a<b?a:b;  }  int dfs(int pos,int flow)  {      if(pos==t) return flow;      int t=0,sum=0;      for(int nex=head[pos];nex!=-1;nex=edge[nex].next)      {          if(deep[edge[nex].v]==deep[pos]+1&&edge[nex].cap>0)          {              t=dfs(edge[nex].v,Min(flow-sum,edge[nex].cap));              if(t>0)              {                  edge[nex].cap-=t;                  edge[nex^1].cap+=t;                  sum+=t;                  if(sum==flow) break;              }              else deep[edge[nex].v]=-1;          }      }      return sum;//当前点可增广的最大流量  }  int dinic()  {      int sum=0;      while(bfs())          sum+=dfs(s,INF);      return sum;  }  void add(int u,int v,int w)  {      //u->v      edge[cnt].v=v;      edge[cnt].cap=w;      edge[cnt].next=head[u];      head[u]=cnt++;      //v->u      edge[cnt].v=u;      edge[cnt].cap=0;      edge[cnt].next=head[v];      head[v]=cnt++;  }  int main()  {      int T,Case;      int S,E,P;      scanf("%d",&T);      for(Case=1;Case<=T;Case++)      {          s=0;          cnt=0;          memset(head,-1,sizeof(head));          scanf("%d%d",&N,&M);          int sum=0,m=-1;          for(int i=1;i<=N;i++)          {              scanf("%d%d%d",&P,&S,&E);              sum+=P;              add(s,500+i,P);     //建边            for(int j=S;j<=E;j++)                  add(500+i,j,1);  //建边        }          t=1001;        for(int i=1;i<=500;i++)              add(i,t,M);  //建边        printf("Case %d: ",Case);          int ans=dinic();          if(ans==sum) printf("Yes\n\n");          else printf("No\n\n");      }  }  


阅读全文
0 0
原创粉丝点击