zoukankan      html  css  js  c++  java
  • hdu 3572 Task Schedule 网络流

    Our geometry princess XMM has stoped her study in computational geometry to concentrate on her newly opened factory. Her factory has introduced M new machines in order to process the coming N tasks. For the i-th task, the factory has to start processing it at or after day Si, process it for Pi days, and finish the task before or at day Ei. A machine can only work on one task at a time, and each task can be processed by at most one machine at a time. However, a task can be interrupted and processed on different machines on different days.
    Now she wonders whether he has a feasible schedule to finish all the tasks in time. She turns to you for help.
     
    题意:有M台机器和N个任务,每个任务必须在第si天到第ei天之间完成,完成一个任务需要pi天(1<=i<=n)。一台机器同时只能做一个任务,一个任务同一时间只能由一台机器处理。问能否完成。
     
    解法:构造成为网络流,然后运用SAP算法求解。
    把每个任务和每个时刻都作为节点,增设一个源点和一个汇点。对于任务i,连接一条源点指向 i 最大容量为pi 的边,然后连接 i 到[ si , ei ]区间里每个时刻,最大容量为1,最后连接每个时刻到汇点,最大容量为m(因为同一时刻最多只能有m台机器在操作)。此时,完成构图。
    用网络流算法求解到最大流之后,判断是不是满流(每个任务都有天数的限制,不能少也不能多)。
    SAP和Dinic算法:这道题里节点1000,边数50w,Dinic+邻接矩阵是不行的了,看到hdu上面有人800+msAC,也许Dinic+邻接表吧。我直接选用各种优化之后的SAP算法。
     
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cstdlib>
      5 #include<cmath>
      6 #include<algorithm>
      7 #include<queue>
      8 #define inf 0x7fffffff
      9 using namespace std;
     10 const int maxn=1000+10;
     11 const int M = 500000+10;
     12 
     13 struct Edge
     14 {
     15     int to,cap,next;
     16 }edge[M];
     17 int head[maxn],edgenum;
     18 int n,m,from,to,vnum;
     19 int level[maxn],gap[maxn];
     20 
     21 void add(int u,int v,int cap)
     22 {
     23     edge[edgenum].to=v;
     24     edge[edgenum].cap=cap;
     25     edge[edgenum].next=head[u];
     26     head[u]=edgenum++;
     27 
     28     edge[edgenum].to=u;
     29     edge[edgenum].cap=0;
     30     edge[edgenum].next=head[v];
     31     head[v]=edgenum++;
     32 }
     33 
     34 void bfs(int to)
     35 {
     36     memset(level,-1,sizeof(level));
     37     memset(gap,0,sizeof(gap));
     38     level[to]=0;
     39     gap[level[to] ]++;
     40     queue<int> Q;
     41     Q.push(to);
     42     while (!Q.empty())
     43     {
     44         int u=Q.front() ;Q.pop() ;
     45         for (int i=head[u] ;i!=-1 ;i=edge[i].next)
     46         {
     47             int v=edge[i].to;
     48             if (level[v] != -1) continue;
     49             level[v]=level[u]+1;
     50             gap[level[v] ]++;
     51             Q.push(v);
     52         }
     53     }
     54 }
     55 
     56 int pre[maxn];
     57 int cur[maxn];
     58 int SAP(int from,int to)
     59 {
     60     bfs(to);
     61     memset(pre,-1,sizeof(pre));
     62     memcpy(cur,head,sizeof(head));
     63     int u=pre[from]=from,flow=0,aug=inf;
     64     gap[0]=vnum;
     65     while (level[from]<vnum)
     66     {
     67         bool flag=false;
     68         for (int &i=cur[u] ;i!=-1 ;i=edge[i].next)
     69         {
     70             int v=edge[i].to;
     71             if (edge[i].cap>0 && level[u]==level[v]+1)
     72             {
     73                 flag=true;
     74                 pre[v]=u;
     75                 u=v;
     76                 aug=min(aug,edge[i].cap);
     77                 if (u==to)
     78                 {
     79                     flow += aug;
     80                     for (u=pre[u] ;v!=from ;v=u,u=pre[u])
     81                     {
     82                         edge[cur[u] ].cap -= aug;
     83                         edge[cur[u]^1 ].cap += aug;
     84                     }
     85                     aug=inf;
     86                 }
     87                 break;
     88             }
     89         }
     90         if (flag) continue;
     91         int minlevel=vnum;
     92         for (int i=head[u] ;i!=-1 ;i=edge[i].next)
     93         {
     94             int v=edge[i].to;
     95             if (edge[i].cap>0 && level[v]<minlevel)
     96             {
     97                 minlevel=level[v];
     98                 cur[u]=i;
     99             }
    100         }
    101         if (--gap[level[u] ]==0) break;
    102         level[u]=minlevel+1;
    103         gap[level[u] ]++;
    104         u=pre[u];
    105     }
    106     return flow;
    107 }
    108 
    109 int main()
    110 {
    111     int t,ncase=1;
    112     scanf("%d",&t);
    113     while (t--)
    114     {
    115         scanf("%d%d",&n,&m);
    116         int p,s,e;
    117         memset(head,-1,sizeof(head));
    118         edgenum=0;
    119         from=0;
    120         int sn[501],en[501],maxe=0;
    121         int sum=0;
    122         for (int i=1 ;i<=n ;i++)
    123         {
    124             scanf("%d%d%d",&p,&s,&e);
    125             sum += p;
    126             sn[i]=s ;en[i]=e ;
    127             maxe=max(maxe,e);
    128             add(from,i,p);
    129             for (int j=s ;j<=e ;j++)
    130             {
    131                 add(i,n+j,1);
    132             }
    133         }
    134         to=maxe+1;
    135         vnum=to+1;
    136         for (int j=1 ;j<=maxe ;j++)
    137             add(n+j,to,m);
    138         int Maxflow=SAP(from,to);
    139         printf("Case %d: ",ncase++);
    140         if (Maxflow==sum) printf("Yes
    ");
    141         else printf("No
    ");
    142         printf("
    ");
    143     }
    144     return 0;
    145 }
  • 相关阅读:
    第四周总结&实验报告二
    第三周实验总结
    2019秋第二周总结
    2019春期末总结
    C语言第四次实验报告
    第三次设计报告
    2019第二次实验设计报告
    2019第一次实验设计报告
    2019第十二周作业
    第五周课程总结&试验报告(三)
  • 原文地址:https://www.cnblogs.com/huangxf/p/4266588.html
Copyright © 2011-2022 走看看