HDU 3572 Task Schedule(最大流判断满流)

https://vjudge.net/problem/HDU-3572

题意:

有N个作业和M台机器,每个作业都有一个持续时间P,工作的日期为S~E。作业可以断断续续的在不同机器上做,每台机器每次只可以处理一个作业。判断是否可以在作业的工作日期内完成所有作业。

思路:

建立源点0和汇点t,因为天数最多为500,所有我们将日期的编号定为1~500,作业的编号为500+i。

对于每个作业,与源点0相连,容量为P,意味着它必须走完这P容量才能完成这作业。与S~E相连,容量为1。日期与汇点相连,容量为m,说明每天能处理m个作业。

最后计算出最大流,如果等于所有作业的P之和,说明是可以完成的。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<cstring>
  5 #include<queue>
  6 using namespace std;
  7 
  8 const int maxn=1000+5;
  9 const int INF=0x3f3f3f3f;
 10 
 11 int n,m;
 12 int ans;
 13 
 14 struct Edge
 15 {
 16     int from,to,cap,flow;
 17     Edge(int u,int v,int w,int f):from(u),to(v),cap(w),flow(f){}
 18 };
 19 
 20 struct Dinic
 21 {
 22     int n,m,s,t;
 23     vector<Edge> edges;
 24     vector<int> G[maxn];
 25     bool vis[maxn];
 26     int cur[maxn];
 27     int d[maxn];
 28 
 29     void init(int n)
 30     {
 31         this->n=n;
 32         for(int i=0;i<n;++i) G[i].clear();
 33         edges.clear();
 34     }
 35 
 36     void AddEdge(int from,int to,int cap)
 37     {
 38         edges.push_back( Edge(from,to,cap,0) );
 39         edges.push_back( Edge(to,from,0,0) );
 40         m=edges.size();
 41         G[from].push_back(m-2);
 42         G[to].push_back(m-1);
 43     }
 44 
 45     bool BFS()
 46     {
 47         queue<int> Q;
 48         memset(vis,0,sizeof(vis));
 49         vis[s]=true;
 50         d[s]=0;
 51         Q.push(s);
 52         while(!Q.empty())
 53         {
 54             int x=Q.front(); Q.pop();
 55             for(int i=0;i<G[x].size();++i)
 56             {
 57                 Edge& e=edges[G[x][i]];
 58                 if(!vis[e.to] && e.cap>e.flow)
 59                 {
 60                     vis[e.to]=true;
 61                     d[e.to]=d[x]+1;
 62                     Q.push(e.to);
 63                 }
 64             }
 65         }
 66         return vis[t];
 67     }
 68 
 69     int DFS(int x,int a)
 70     {
 71         if(x==t || a==0) return a;
 72         int flow=0, f;
 73         for(int &i=cur[x];i<G[x].size();++i)
 74         {
 75             Edge &e=edges[G[x][i]];
 76             if(d[e.to]==d[x]+1 && (f=DFS(e.to,min(a,e.cap-e.flow) ) )>0)
 77             {
 78                 e.flow +=f;
 79                 edges[G[x][i]^1].flow -=f;
 80                 flow +=f;
 81                 a -=f;
 82                 if(a==0) break;
 83             }
 84         }
 85         return flow;
 86     }
 87 
 88     int Maxflow(int s,int t)
 89     {
 90         this->s=s;
 91         this->t=t;
 92         int flow=0;
 93         while(BFS())
 94         {
 95             memset(cur,0,sizeof(cur));
 96             flow +=DFS(s,INF);
 97         }
 98         return flow;
 99     }
100 }DC;
101 
102 int main()
103 {
104     //freopen("D:\input.txt","r",stdin);
105     int T;
106     int kase=0;
107     scanf("%d",&T);
108     while(T--)
109     {
110         scanf("%d%d",&n,&m);
111         ans=0;
112         DC.init(500+2+n);
113 
114         bool vis[maxn];//表示第i天是否被用到
115         memset(vis,0,sizeof(vis));
116 
117         for(int i=1;i<=n;++i)
118         {
119             int P,S,E;
120             scanf("%d%d%d",&P,&S,&E);
121             DC.AddEdge(0,500+i,P);
122             ans += P;
123             for(int j=S;j<=E;++j)
124             {
125                 DC.AddEdge(500+i,j,1);
126                 vis[j]=true;
127             }
128         }
129 
130         for(int i=1;i<=500;++i)if(vis[i])//被任务覆盖的日子才添加
131             DC.AddEdge(i,500+n+1,m);
132         printf("Case %d: %s

",++kase,DC.Maxflow(0,500+n+1)==ans?"Yes":"No");
133     }
134     return 0;
135 }
原文地址:https://www.cnblogs.com/zyb993963526/p/6683308.html