zoukankan      html  css  js  c++  java
  • hdu 3572 Task Schedule(最大流)2010 ACM-ICPC Multi-University Training Contest(13)——Host by UESTC

    题意:

    告诉我们有m个任务和k个机器。第i个任务需要ci天完成,最早从第ai天开始,最晚在第bi天结束。每台机器每天可以执行一个任务。问,是否可以将所有的任务都按时完成?

    输入:

    首行输入一个整数t,表示共有t组数据。

    接下来,每组数据第一行输入两个整数k,m,表示共有k项任务,m台机器。

    接下来k行,每行包括三个整数ci,ai,bi。

    输出:

    如果可以完成所有任务,输出——Case i: Yes

     

    否则,输出——Case t: No

    注意,每组输出占2行

    这道题我如何也想不到是个最大流。即使我知道这是最大流,我也想不出来如何建图。看了题解后,才恍然大悟。

    题解:

    首先建立一个超级源点0.

    从1到k表示k项任务的节点,ki表示第i项任务。

    从k+1到m+k表示机器的节点,第k+mi表示第mi台机器。

    从m+k+1到m+k+l表示时间的节点。第m+k+li表示第li天。

    最后一个超级汇点m+k+l+1。

    然后从0到ki用ci连接——mp[0][ki] = ci; 表示第ki项任务需要执行ci天。

    从ki到m+k+lj用1连接——mp[ki][m+k+lj] = 1; 表示第ki项任务在第lj天执行一天。

    从m+k+lj到k+mi用1连接——mp[m+k+lj][k+mi] = 1; 表示第lj天使用了mi一天。

    然后从k+mi到m+k+l+1用l连接——mp[k+mi][m+k+l+1] = l; 表示第mi台机器最多可以使用l天。

    接下来将这张图进行运算。如果最大流等于,则可以完成。

    同样使用Dinic算法。

    上代码——

      1 #include <cstdio>
      2 #include <cmath>
      3 #include <cstring>
      4 #include <algorithm>
      5 #include <queue>
      6 using namespace std;
      7 
      8 const int N = 2010;
      9 const int M = 10000010;
     10 
     11 int mp[N][N];
     12 int dis[N];
     13 int cur[N];
     14 bool vis[N];
     15 int t, k, m, n, l, ans, sum;
     16 
     17 inline int Min(int x, int y)
     18 {
     19     return x < y ? x : y;
     20 }
     21 
     22 void init()             //神奇的建图
     23 {
     24     scanf("%d%d", &k, &m);
     25     l = 0;
     26     sum = 0;
     27     memset(mp, 0, sizeof(mp));
     28     for(int i = 1; i <= k; i++)
     29     {
     30         int a, b, c;
     31         scanf("%d%d%d", &c, &a, &b);
     32         if(l < b) l = b;
     33         mp[0][i] = c;
     34         sum += c;
     35         for(int j = a; j <= b; j++)
     36         {
     37             mp[i][k+m+j] = 1;
     38         }
     39     }
     40     n = k+m+l+1;
     41     for(int i = 1; i <= m; i++)
     42     {
     43         for(int j = 1; j <= l; j++) mp[m+k+j][k+i] = 1;
     44         mp[k+i][n] = l;
     45     }
     46     ans = 0;
     47 }
     48 
     49 bool bfs()
     50 {
     51     memset(vis, 0, sizeof(vis));
     52     queue<int> que;
     53     que.push(0);
     54     vis[0] = 1;
     55     dis[0] = 0;
     56     while(!que.empty())
     57     {
     58         int k = que.front();
     59         que.pop();
     60         for(int i = 0; i <= n; i++)
     61         {
     62             if(!vis[i] && mp[k][i] > 0)
     63             {
     64                 vis[i] = 1;
     65                 dis[i] = dis[k]+1;
     66                 que.push(i);
     67             }
     68         }
     69     }
     70     return vis[n];
     71 }
     72 
     73 int dfs(int x, int val)
     74 {
     75     if(x == n || val == 0) return val;
     76     int flow = 0, minn;
     77     for(int& i = cur[x]; i <= n; i++)
     78     {
     79         if(dis[x]+1 == dis[i] && (minn = dfs(i, Min(val, mp[x][i]))) > 0)
     80         {
     81             mp[x][i] -= minn;
     82             mp[i][x] += minn;
     83             val -= minn;
     84             flow += minn;
     85             if(val == 0) break;
     86         }
     87     }
     88     return flow;
     89 }
     90 
     91 void work()         //开始搜图,即使用Dinic算法
     92 {
     93     while(bfs())
     94     {
     95         for(int i = 0; i <= n; i++) cur[i] = 0;
     96         ans += dfs(0, M);
     97     }
     98 }
     99 
    100 void outit(int tm)
    101 {
    102     printf("Case %d: ", tm);
    103     if(ans == sum) printf("Yes
    
    ");
    104     else printf("No
    
    ");
    105 }
    106 
    107 int main()
    108 {
    109     //freopen("test.in", "r", stdin);
    110     scanf("%d", &t);
    111     for(int tm = 1; tm <= t; tm++)
    112     {
    113         init();
    114         work();
    115         outit(tm);
    116     }
    117     return 0;
    118 }
    View Code

    只是别人使用15ms,我用300+ms。看来还是需要优化啊。

  • 相关阅读:
    websocket
    svg vs canvas
    nw
    web sql
    web worker
    【转载】磁盘阵列详解
    【识记】开源软件系列
    【转载】从1.5K到18K 一个程序员的5年成长之路
    SQL中in和not in
    SQL Server select count(distinct *)
  • 原文地址:https://www.cnblogs.com/mypride/p/4859612.html
Copyright © 2011-2022 走看看