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\n");
141         else printf("No\n");
142         printf("\n");
143     }
144     return 0;
145 }

 

posted @ 2015-02-01 23:36  huangxf  阅读(329)  评论(0编辑  收藏  举报