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 }

 

你可能感兴趣的:(schedule)