HDU 3572 Task Schedule 网络流 ISAP

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

题意:

  给出N个任务,M个机器,每天每台机器只能处理一件事,接下来N行,每行有p s e

分别表示这个任务要用p天,要在s~e天完成,问你这所有任务能不能完成。

 

坑爹:

  模板题,注意一下vector数组clear的时候控制好长度,有可能会超时。

 

解法:

  将N个任务标号为1~N,用个max_Day来找最大的天数,然后天数的标号为

N+1~max_Day+N , 建立一个源点0,汇点max_Day+N+1。

建图的步骤:先将所有任务与源点相连,权值为完成所需天数,再将这个任务与再这个任务范围

内的时间(天)相连,权值为1,最后将每个时间与汇点相连,权值为M,因为只有M个机器。

 

  1 #include<iostream>
  2 #include<stdio.h>
  3 #include<vector>
  4 #include<queue>
  5 using namespace std;
  6 
  7 const int maxn = 500000 + 10;
  8 const int INF = 0x3fffffff;
  9 
 10 struct Edge {
 11     int from;
 12     int to;
 13     int cap;
 14     int flow;
 15 }edge[2*maxn];
 16 vector<int> G[maxn];
 17 int head[maxn];
 18 int cur[maxn];
 19 bool used[maxn];
 20 int deep[maxn];
 21 int front[maxn];
 22 int gap[maxn];
 23 int cnt;
 24 int N;
 25 int M;
 26 
 27 void addEdge(int from, int to, int cap)
 28 {
 29     edge[cnt].from = from;
 30     edge[cnt].to = to;
 31     edge[cnt].cap = cap;
 32     edge[cnt].flow = 0;
 33     cnt ++;
 34 
 35     edge[cnt].from = to;
 36     edge[cnt].to = from;
 37     edge[cnt].cap = 0;
 38     edge[cnt].flow = 0;
 39     cnt ++;
 40 
 41     G[from].push_back(cnt-2);
 42     G[to].push_back(cnt-1);
 43 }
 44 
 45 bool BFS(int s, int t)
 46 {
 47     memset(used,0,sizeof(used));
 48     queue<int> Q;
 49     Q.push(t);
 50     deep[t] = 0;
 51     used[t] = true;
 52     while(!Q.empty())
 53     {
 54         int top = Q.front();
 55         Q.pop();
 56         int i;
 57         for(i=0; i<G[top].size(); i++)
 58         {
 59             Edge e = edge[G[top][i]];
 60             if(!used[e.to])
 61             {
 62                 used[e.to] = true;
 63                 deep[e.to] = deep[top] + 1;
 64                 Q.push(e.to);
 65             }
 66         }
 67     }
 68     return used[s];
 69 }
 70 
 71 int Augment(int s,int t)
 72 {
 73     int begin = t;
 74     int minFlow = INF;
 75     while(begin != s)
 76     {
 77         Edge& e = edge[front[begin]];
 78         minFlow = min(minFlow, e.cap-e.flow);
 79         begin = edge[front[begin]].from;
 80     }
 81     begin = t;
 82     while(begin != s)
 83     {
 84         edge[front[begin]].flow += minFlow;
 85         edge[front[begin]^1].flow -= minFlow;
 86         begin = edge[front[begin]].from;
 87     }
 88     return minFlow;
 89 }
 90 
 91 int Maxflow(int s,int t)
 92 {
 93     int flow = 0;
 94     BFS(s,t);
 95     memset(gap,0,sizeof(gap));
 96     memset(cur,0,sizeof(cur));
 97     int i;
 98     for(i=0; i<=N; i++)
 99     {
100         gap[deep[i]] ++;
101     }
102     int begin = s;
103     while(deep[s] < N)
104     {
105         if(begin == t)
106         {
107             flow += Augment(s,t);
108             begin = s;
109         }
110         bool ok = false;
111         int i;
112         for(i=cur[begin]; i<G[begin].size(); i++)
113         {
114             Edge& e = edge[G[begin][i]];
115             if(e.cap > e.flow && deep[begin] == deep[e.to] + 1)
116             {
117                 ok = true;
118                 front[e.to] = G[begin][i];
119                 cur[begin] = i;
120                 begin = e.to;
121                 break;
122             }
123         }
124         if(!ok)
125         {
126             int m = N - 1;
127             int i;
128             for(i=0; i<G[begin].size(); i++)
129             {
130                 Edge& e = edge[G[begin][i]];
131                 if(e.cap > e.flow)
132                 {
133                     m = min(m, deep[e.to]);
134                 }
135             }
136             if(--gap[deep[begin]] == 0)
137             {
138                 break;
139             }
140             gap[deep[begin] = m+1] ++;
141             cur[begin] = 0;
142             if(begin != s)
143             {
144                 begin = edge[front[begin]].from;
145             }
146         }
147     }
148     return flow;
149 }
150 
151 int main()
152 {
153     int T;
154     scanf("%d",&T);
155     int Case;
156     int machine;
157     int s = 0;
158     int t = 0;
159     for(Case=1; Case<=T; Case++)
160     {
161         scanf("%d%d",&M,&machine);//M 任务数量 ,machine 机器数量
162         int i;
163         for(i=0; i<=t; i++)
164         {
165             G[i].clear();
166         }
167         cnt = 0;
168         int max_Day = 0;
169         memset(deep,0,sizeof(deep));
170         int sum_Task = 0;
171         for(i=1; i<=M; i++)
172         {
173             int p;
174             int s;
175             int e;
176             scanf("%d%d%d",&p,&s,&e);
177             sum_Task += p;
178             if(e > max_Day)
179             {
180                 max_Day = e;
181             }
182             addEdge(0,i,p);
183             int j;
184             for(j=s+M; j<=e+M; j++)
185             {
186                 addEdge(i,j,1);
187             }
188         }
189         s = 0;//源点
190         t = max_Day+M+1;//汇点
191         N = t;
192         for(i=M+1; i<=max_Day+M; i++)
193         {
194             addEdge(i,t,machine);
195         }
196         int flow = Maxflow(s,t);
197         if(sum_Task == flow)
198         {
199             printf("Case %d: Yes\n\n",Case);
200         }
201         else
202         {
203             printf("Case %d: No\n\n",Case);
204         }
205     }
206     //system("pause");
207     return 0;
208 }
View Code

 

posted @ 2013-09-05 11:07  pc....  阅读(868)  评论(0)    收藏  举报