HDU 2883 kebab(最大流)

【题意】

有一个烤肉机,每次可以同时烤M份肉。有N个顾客,第i个顾客li时刻到达,ri时刻走, 点了ai份肉,每份肉需要bi的时间烤,客人的每份肉可以分开烤,比如一份肉需要t时间烤,如果平均分出t份,那么能在1个时间内烤完。问能否满足所有顾客的需求。

【分析】

烤肉机相当于每个单位时间段都在工作,可以一直往里面加肉,每个单位时间段最多可以容下M份肉。对于每个客人,其需求需要在(li,ri)的区间内 完成,因为烤肉可以分开烤,则只需考虑单位份烤肉所需时间然后累加,即只用考虑ai*bi <=(ri - li)*M,如果满足,那么这个顾客是可以满足的。显然,问题转化为区间覆盖问题。

线段上每个单位线段的容量为M,每个顾客的区间为(li,ri),其顾客容量为ai*bi。求能否覆盖完

【建图】

由以上分析,可以由源点到每个顾客i连边,容量为ai*bi;由每个单位时间段向汇点连边,容量为M;每个顾客i对每个时间段j连边,容量为INF.跑最大流判定即可。但是时间点有100W个,不可行。

【离散化】把时间点离散化成很多个区间,最多2*N-1 个区间。每个区间j,向汇点连边(ri - li)*M。每个顾客i向每个区间j连边,如果顾客的时间段覆盖了区间,容量为INF.

【Mark】注意建图一共有600+点,这里导致WA 2发。

复制代码
  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<math.h>
  4 #include<algorithm>
  5 
  6 using namespace std;
  7 
  8 #define INF 1e8
  9 #define MAX_VECT 605
 10 #define MAX_EDGE 2200000
 11 
 12 /************************************************************************/
 13 
 14 /*    Name: dinic
 15 /*  Description: Find the max flow of the network from start to
 16                  end point
 17 /*  Variable Description: to[] - end point of the current edge
 18                           next[] - the next edge which also comes from
 19                                    the same point as current edge
 20                           cap[] - the capability of the current edge
 21                           v[] - the first edge index which comes from the
 22                                 the current point
 23                           d[] - the layer number of current point
 24 /************************************************************************/
 25 
 26 
 27 int to[MAX_EDGE], next[MAX_EDGE], cap[MAX_EDGE], tot;
 28 int v[MAX_VECT], d[MAX_VECT], queue[MAX_VECT], n;
 29 int S, T;
 30 inline void single_insert(int _u, int _v, int var)
 31 {
 32     to[tot] = _v;
 33     cap[tot] = var;
 34     next[tot] = v[_u];
 35     v[_u] = tot++;
 36 }
 37 
 38 void insert(int from, int to,  int cap)
 39 {
 40     single_insert(from, to, cap);
 41     single_insert(to, from, 0);
 42 }
 43 
 44 bool bfs_initial()
 45 {
 46     memset(d, -1, sizeof(d));
 47     int bg, ed, x, y;
 48     bg = ed = d[S] = 0;
 49     queue[ed++] = S;
 50     while (bg < ed)
 51     {
 52         x = queue[bg++];
 53         for (int i = v[x]; i+1; i = next[i])
 54         {
 55             y = to[i];
 56             if (cap[i] && d[y] == -1)
 57             {
 58                 d[y] = d[x] + 1;
 59                 if (y == T) return true;
 60                 queue[ed++] = y;
 61             }
 62         }
 63     }
 64     return false;
 65 }
 66 
 67 int Find(int x, int low = INF)
 68 {
 69     if (x == T) return low;
 70     int ret, y, ans = 0;
 71     for (int i = v[x]; (i+1) && low; i = next[i])
 72     {
 73         y = to[i];
 74         if (cap[i] && d[y] == d[x] + 1 && (ret = Find(y, min(low, cap[i]))))
 75         {
 76             cap[i] -= ret;
 77             cap[i^1] += ret;
 78             low -= ret;
 79             ans += ret;
 80         }
 81     }
 82     return ans;
 83 }
 84 int dinic()
 85 {
 86     int ans = 0;
 87     while (bfs_initial())
 88         ans += Find(S);
 89     return ans;
 90 }
 91 
 92 
 93 int dinicc()
 94 {
 95     int ans = 0;
 96     while(bfs_initial())
 97     {
 98         int edge, x, y, back, iter = 1;
 99         while(iter)
100         {
101             x = (iter == 1) ? S : to[queue[iter - 1]];
102             if (x == T)
103             {
104                 int minE, minCap = INF;
105                 for (int i = 1; i < iter; i++)
106                 {
107                     edge = queue[i];
108                     if (cap[edge] < minCap)
109                     {
110                         minCap = cap[edge];
111                         back = i;
112                     }
113                 }
114                 for (int i = 1; i < iter; i++)
115                 {
116                     edge = queue[i];
117                     cap[edge] -= minCap;
118                     cap[edge ^ 1] += minCap;
119                 }
120                 ans += minCap;
121                 iter = back;
122             }
123             else
124             {
125                 for (edge = v[x]; edge + 1; edge = next[edge])
126                 {
127                     y = to[edge];
128                     if (cap[edge] && d[y] == d[x] + 1)
129                         break;
130                 }
131                 if (edge+1)
132                     queue[iter++] = edge;
133                 else
134                 {
135                     d[x] = -1;
136                     iter--;
137                 }
138             }
139         }
140     }
141     return ans;
142 }
143 int m;
144 struct time{
145     int l,r;
146     int a,b;
147 }seq[MAX_VECT];
148 int ttt[MAX_VECT*2];
149 int cnt = 0;
150 
151 int check(int L,int R,int l,int r)
152 {
153     return (L<=l && r<=R);
154 }
155 int main()
156 {
157     while (scanf("%d%d",&n,&m)==2)
158     {
159         tot = 0;
160         memset(v,-1,sizeof(v));
161         cnt = 0;
162         for (int i=1;i<=n;i++)
163         {
164             scanf("%d%d%d%d",&seq[i].l,&seq[i].a,&seq[i].r,&seq[i].b);
165             ttt[++cnt] = seq[i].l;
166             ttt[++cnt] = seq[i].r;
167         }
168         sort(ttt+1,ttt+1+cnt);
169 
170         S = 0;
171         T = n + cnt;
172         int sum = 0;
173         for (int i=1;i<=n;i++)
174         {
175             insert(S,i,seq[i].a*seq[i].b);
176             sum += seq[i].a * seq[i].b;
177         }
178         for (int i=1;i<cnt;i++)
179         {
180             insert(n+i,T,(ttt[i+1] - ttt[i])*m);
181         }
182         for (int i=1;i<=n;i++)
183             for (int j=1;j<cnt;j++)
184             {
185                 if (check(seq[i].l, seq[i].r, ttt[j],ttt[j+1]))
186                 {
187                     insert(i,n+j,INF);
188                 }
189             }
190 
191         n = n + cnt;
192 
193         int ans = dinic();
194         if (ans == sum)
195             printf("Yes\n");
196         else
197             printf("No\n");
198     }
199     return 0;
200 }
hdu2883
复制代码

 

 

/****

Author:wangsouc

****/

posted @ 2013-09-02 17:22  oucacm  阅读(114)  评论(0)    收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示