HDU - 3572 Task Schedule(网络流)(入门好题)

原题链接

题意:

有 $m$ 台机器,一台机器同一时刻只能够做一个任务,任务可以被中断并给另一个空闲的机器去完成;

现在有 $n$ 个任务,每个任务有 $Pi , si , ei $, 分别表示该任务完成所需要的  任务量,开始时间,截止时间;

问  是否能够在规定时间内完成所有任务。

思路:

设定 $S = 0$ 为超级源点,将 $S$ 与每一个任务点相连,流量为$P[i]$,每个任务点与其 $si$ 到 $ei$ 范围内相连,流量为1,最后将所有任务的时间区间与 $T$ 相连,流量为 $m$;

跑一遍最大流之后判断是否大于  $\sum_{i=1}^{n} Pi $,若大于等于,则能够完成所给的任务,反之则不能。  感觉是一道比较好的网络流入门题目

 

  1 /*
  2 * @Author: WindyStreet
  3 * @Date:   2018-07-31 16:00:05
  4 * @Last Modified by:   WindyStreet
  5 * @Last Modified time: 2018-07-31 19:14:55
  6 */
  7 #include<bits/stdc++.h>
  8 
  9 using namespace std;
 10 
 11 #define X first
 12 #define Y second
 13 #define eps  1e-2
 14 #define gcd __gcd
 15 #define pb push_back
 16 #define PI acos(-1.0)
 17 #define lowbit(x) (x)&(-x)
 18 #define bug printf("!!!!!\n");
 19 #define mem(x,y) memset(x,y,sizeof(x))
 20 
 21 typedef long long LL;
 22 typedef long double LD;
 23 typedef pair<int,int> pii;
 24 typedef unsigned long long uLL;
 25 
 26 const int maxn = 1e3+2;
 27 const int INF  = 1<<30;
 28 const int mod  = 1e9+7;
 29 
 30 struct Edge{
 31      int from,to,cap,flow;
 32 };
 33 struct node
 34 {
 35     int p,s,e;
 36 }s[maxn];
 37 
 38 struct Dinic
 39 {
 40     int n,m,s,t;
 41     vector<Edge>edge;
 42     vector<int>G[maxn];
 43     bool vis[maxn];
 44     int d[maxn];
 45     int cur[maxn];
 46     void init(int n){
 47         this->n = n;
 48         for(int i=0;i<=n;i++)G[i].clear(),edge.clear();
 49     }
 50     void addedge(int from,int to,int cap){
 51         edge.pb((Edge){from,to,cap,0});
 52         edge.pb((Edge){to,from,0,0});
 53         m = edge.size();
 54         G[from].pb(m-2);
 55         G[to].pb(m-1);
 56     }
 57     bool bfs(){
 58         mem(vis,0);
 59         queue<int>Q;
 60         Q.push(s);
 61         d[s] = 0;
 62         vis[s] = 1;
 63         while(!Q.empty()){
 64             int x = Q.front(); Q.pop();
 65             int sz = G[x].size();
 66             for(int i=0;i<sz;++i){
 67                 Edge &e = edge[G[x][i]];
 68                 if(!vis[e.to] && e.cap>e.flow){
 69                     vis[e.to] = 1 ;
 70                     d[e.to] = d[x] + 1;
 71                     Q.push(e.to); 
 72                 }
 73             }
 74         }
 75         return vis[t];
 76     }
 77     int dfs(int x,int a){
 78         if(x == t || a == 0)return a;
 79         int flow = 0,f;
 80         int sz = G[x].size();
 81         for(int &i = cur[x];i<sz;i++){
 82             Edge &e = edge[G[x][i]];
 83             if(d[x] + 1 == d[e.to] && (f = dfs(e.to,min(a,e.cap - e.flow)))>0){
 84                 e.flow += f;
 85                 edge[G[x][i]^1].flow -=f;
 86                 flow += f;
 87                 a -= f;
 88                 if(a==0)break;
 89             }
 90         }
 91         if(!flow) d[x] = -2;
 92         return flow;
 93     }
 94     int maxflow(int s,int t){
 95         this->s = s; this -> t = t;
 96         int flow = 0;
 97         while(bfs()){
 98             mem(cur,0);
 99             flow += dfs(s,INF);
100         }
101         return flow;
102     }
103 };
104 
105 void solve(){
106     int n,m,len = -1,st = 0,ed = 1001,sum = 0;
107     Dinic dinic;
108     scanf("%d%d",&n,&m);
109     for(int i=1;i<=n;i++){
110         scanf("%d%d%d",&s[i].p,&s[i].s,&s[i].e);    
111         len = max(len,s[i].e);                            // 记录最大的时间
112         sum += s[i].p;
113         dinic.addedge(st,i,s[i].p);                        // 将 S 与每个任务点相连
114         for(int j = s[i].s ;j <= s[i].e;j++ ){
115             dinic.addedge(i,j+n,1);                        // 将每个任务点与其相对应的时间区间相连
116         }
117     }
118     for(int i = 1;i<=len;i++)
119     {
120         dinic.addedge(i+n,ed,m);                        // 将所有的时间区间与 T汇点相连
121     }
122     int ans = dinic.maxflow(st,ed);
123     if(sum<=ans){                                         // 判断最大流是否大于等于所需时间
124         printf("Yes\n\n");
125     }else{
126         printf("No\n\n");
127     }
128     return;
129 }
130 
131 int main()
132 {
133 //    freopen("in.txt","r",stdin);
134 //    freopen("out.txt","w",stdout);
135 //    ios::sync_with_stdio(false);
136     int t = 1,cas = 1;
137     scanf("%d",&t);
138     while(t--){
139         printf("Case %d: ",cas++);
140         solve();
141     }
142     return 0;
143 }

 

posted @ 2018-07-31 19:31  windystreet  阅读(222)  评论(0编辑  收藏  举报