hdu-3572 Task Schedule---最大流判断满流+dinic算法

题目链接:

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

题目大意:

给N个任务,M台机器。每个任务有最早才能开始做的时间S,deadline E,和持续工作的时间P。每个任务可以分段进行,但是在同一时刻,一台机器最多只能执行一个任务. 问存不存在可行的工作时间。

解题思路:

由于时间<=500且每个任务都能断断续续的执行,那么我们把每一天时间作为一个节点来用网络流解决该题.

       建图: 源点s(编号0), 时间1-500天编号为1到500, N个任务编号为500+1 到500+N, 汇点t(编号501+N).

       源点s到每个任务i有边(s, i, Pi)

       每一天到汇点有边(j, t, M) (其实这里的每一天不一定真要从1到500,只需要取那些被每个任务覆盖的每一天即可)

       如果任务i能在第j天进行,那么有边(i, j, 1) 注意由于一个任务在一天最多只有1台机器执行,所以该边容量为1,不能为INF或M哦.

最后看最大流是否 == 所有任务所需要的总天数.

用增广路最大流会超时,得用dinic算法优化找增广路

(图论的题目难在如何建图,而不是算法的使用)

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 const int maxn = 1000 + 10;
  5 const int INF = 1e9;
  6 struct edge
  7 {
  8     int u, v, c, f;
  9     edge(){}
 10     edge(int u, int v, int c, int f):u(u), v(v), c(c), f(f){}
 11 };
 12 vector<edge>e;
 13 vector<int>G[maxn];
 14 int level[maxn];//BFS分层
 15 int iter[maxn];//当前弧优化
 16 int n, m;
 17 void init()
 18 {
 19     for(int i = 0; i < maxn; i++)G[i].clear();
 20     e.clear();
 21 }
 22 void addedge(int u, int v, int c)
 23 {
 24     e.push_back(edge(u, v, c, 0));
 25     e.push_back(edge(v, u, 0, 0));
 26     int m = e.size();
 27     G[u].push_back(m - 2);
 28     G[v].push_back(m - 1);
 29 }
 30 void BFS(int s)
 31 {
 32     memset(level, -1, sizeof(level));
 33     queue<int>q;
 34     level[s] = 0;
 35     q.push(s);
 36     while(!q.empty())
 37     {
 38         int u = q.front();
 39         q.pop();
 40         for(int i = 0; i < G[u].size(); i++)
 41         {
 42             edge& now = e[G[u][i]];
 43             int v = now.v;
 44             if(now.c > now.f && level[v] < 0)
 45             {
 46                 level[v] = level[u] + 1;
 47                 q.push(v);
 48             }
 49         }
 50     }
 51 }
 52 int dfs(int u, int t, int f)//u为当前点,t为终点,f为当前流量
 53 {
 54     if(u == t)return f;
 55     for(int& i = iter[u]; i < G[u].size(); i++)//当前弧优化
 56     {
 57         edge& now = e[G[u][i]];
 58         int v = now.v;
 59         if(now.c > now.f && level[u] < level[v])
 60         {
 61             int d = dfs(v, t, min(f, now.c - now.f));
 62             if(d > 0)
 63             {
 64                 now.f += d;
 65                 e[G[u][i] ^ 1].f -= d;
 66                 return d;
 67             }
 68         }
 69     }
 70     return 0;
 71 }
 72 int Maxflow(int s, int t)
 73 {
 74     int flow = 0;
 75     for(;;)
 76     {
 77         BFS(s);
 78         if(level[t] < 0)return flow;
 79         memset(iter, 0, sizeof(iter));
 80         int f;
 81         while((f = dfs(s, t, INF)) > 0)flow += f;
 82     }
 83     return flow;
 84 }
 85 int main()
 86 {
 87     int T, cases = 0;
 88     scanf("%d", &T);
 89     while(T--)
 90     {
 91         scanf("%d%d", &n, &m);
 92         int maxday = 0;
 93         int sumday = 0;
 94         init();
 95         int p, s, e;
 96         for(int i = 1; i <= n; i++)
 97         {
 98             scanf("%d%d%d", &p, &s, &e);
 99             addedge(0, 500 + i, p);
100             for(int j = s; j <= e; j++)
101                 addedge(i + 500, j, 1);
102             maxday = max(maxday, e);
103             sumday += p;
104         }
105         for(int i = 1; i <= maxday; i++)
106             addedge(i, 501 + n, m);
107         if(Maxflow(0, 501 + n) == sumday)
108             printf("Case %d: Yes\n\n", ++cases);
109         else printf("Case %d: No\n\n", ++cases);
110     }
111     return 0;
112 }

 

posted @ 2018-04-22 22:29  _努力努力再努力x  阅读(171)  评论(0编辑  收藏  举报