牛客暑假多校第二场 F trade

题意: 白兔有n个仓库,每个仓库有啊ai个货物,在每个仓库白兔可以装上任意数量的货物,也可以卸下任意数量的货物,现在有k个圆形信号阻隔器,然后有m个顾客下个一个订单,每个顾客的收货量有一个上限, 在每个订单中,白兔都会走过si个仓库, 从s[0] 按(输入)顺序依次遍历所有仓库, 当白兔遍历完所有仓库之后白兔会就会把车上的货物送到顾客家里。如果某个仓库和顾客的连线在某个圆形信号阻隔器的覆盖范围之内,那么白兔就不会去这个仓库。 求最后白兔给所有顾客的总的货物最多是多少。

题解:由于白兔在每个仓库的时候可以拿/放任意货物, 也就相当于白兔走过的仓库就已经是连起来了, 所以每次到一个新的仓库之后, 他就可以与前一个仓库所链接的所有仓库相连接了(单向),因为可以将连接的仓库的所有货物都放在这个仓库, 然后这个仓库到下一个仓库的时候就可以将这些货物带到下一个仓库, 也就是说仓库(单向)相连了, 可以任意的从前面的仓库把货物拿过来。 然后就是网络流模型了, 将每个仓库都与源点相连, 边值为货物数量上限, 每个顾客与可以走的仓库连线,边值为inf,所有顾客再与汇点相连,边值为顾客的最大收货量。 再跑一遍 s -> t的最大网络流就是答案了。

代码:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
  4 #define LL long long
  5 #define ULL unsigned LL
  6 #define fi first
  7 #define se second
  8 #define pb push_back
  9 #define lson l,m,rt<<1
 10 #define rson m+1,r,rt<<1|1
 11 #define max3(a,b,c) max(a,max(b,c))
 12 #define min3(a,b,c) min(a,min(b,c))
 13 #define db double
 14 double eps = 1e-8;
 15 typedef pair<int,int> pll;
 16 const int inf = 0x3f3f3f3f;
 17 const LL INF = 0x3f3f3f3f3f3f3f3f;
 18 const LL mod =  (int)1e9+7;
 19 const int N = 2e3+55;
 20 const int M = 3e6+100;
 21 int n, m, k;
 22 bitset<N>bit[N];
 23 int x1[N], y11[N], x3[N], y3[N], r[N], a[N];
 24 int x2[N], y2[N];
 25 struct Point{
 26     double x, y;
 27     Point(double _x, double _y){x = _x, y = _y;}
 28     double len(){return sqrt(x * x + y * y);}
 29     Point operator-(const Point &_){
 30         return Point(x - _.x, y - _.y);
 31     }
 32     double operator*(const Point &_){
 33         return x * _.y - y * _.x;
 34     }
 35     double operator%(const Point &_){
 36         return x * _.x + y * _.y;
 37     }
 38 };
 39 
 40 bool ok(int x, int y, int id){
 41     for (int h = 1; h <= k; h ++){
 42         Point A = Point(x1[id], y11[id]), B = Point(x, y), P = Point(x3[h], y3[h]);
 43         Point result(0, 0);
 44         double t = ((P - A) % (B - A)) / ((B - A) % (B - A));
 45         if (t >= 0 && t <= 1){
 46             result = Point(A.x + (B.x - A.x) * t, A.y + (B.y - A.y) * t);
 47         }
 48         else{
 49             if ((P - A) % (P - A) < (P - B) % (P - B))
 50                 result = A;
 51             else
 52                 result = B;
 53         }
 54         if ((P - result) % (P - result) < r[h] * r[h] + eps) return 0;
 55     }
 56     return 1;
 57 }
 58 
 59 int head[N], to[M], nx[M];
 60 LL w[M];
 61 int deep[N], cur[N];
 62 int tot;
 63 int sz;
 64 void add(int u, int v, LL val){
 65     w[tot]  = val; to[tot] = v;
 66     nx[tot] = head[u]; head[u] = tot++;
 67 }
 68 int bfs(int s, int t){
 69     queue<int> q;
 70     memset(deep, 0, sizeof(int)*sz);
 71     q.push(s);
 72     deep[s] = 1;
 73     while(!q.empty()){
 74         int u = q.front();
 75         q.pop();
 76         for(int i = head[u]; ~i; i = nx[i]){
 77             if(w[i] > 0 && deep[to[i]] == 0){
 78                 deep[to[i]] = deep[u] + 1;
 79                 q.push(to[i]);
 80             }
 81         }
 82     }
 83     return deep[t] > 0;
 84 }
 85 LL Dfs(int u, int t, LL flow){
 86     if(u == t) return flow;
 87     for(int &i = cur[u]; ~i; i = nx[i]){
 88         if(deep[u]+1 == deep[to[i]] && w[i] > 0){
 89             LL di = Dfs(to[i], t, min(w[i], flow));
 90             if(di > 0){
 91                 w[i] -= di, w[i^1] += di;
 92                 return di;
 93             }
 94         }
 95     }
 96     return 0;
 97 }
 98 LL Dinic(int s, int t){
 99     LL ans = 0, tmp;
100     while(bfs(s, t)){
101         for(int i = 0; i <= sz; i++) cur[i] = head[i];
102         while(tmp = Dfs(s, t, INF)) ans += tmp;
103     }
104     return ans;
105 }
106 void init(int _sz){
107     memset(head, -1, sizeof(head));
108     tot = 0;
109     sz = _sz;
110 }
111 
112 int main(){
113     scanf("%d%d%d", &n, &m, &k);
114     int s = 0, t = n+m+1;
115     init(t+1);
116     for(int i = 1; i <= n; i++){
117         scanf("%d%d%d", &x1[i], &y11[i], &a[i]);
118         add(s,i,a[i]);
119         add(i,s,0);
120         bit[i][i] = 1;
121     }
122     for(int i = 1; i <= k; i++)
123         scanf("%d%d%d", &x3[i], &y3[i], &r[i]);
124     int x, y, lim, b, c;
125     for(int i = 1; i <= m; i++){
126         scanf("%d%d%d%d", &x, &y, &b, &lim);
127         int last = 0;
128         while(b--){
129             scanf("%d", &c);
130             if(ok(x,y,c)) {
131                 if(last) bit[c] |= bit[last];
132                 last = c;
133             }
134         }
135         if(!last) continue;
136         add(n+i, t, lim);
137         add(t, n+i, 0);
138         for(int j = 1; j <= n; j++)
139            if(bit[last][j]){
140               add(j, n+i, INF);
141               add(n+i, j, 0);
142         }
143     }
144     printf("%lld\n",Dinic(s,t));
145     return 0;
146 }
View Code

 

posted @ 2018-07-24 09:15  Schenker  阅读(274)  评论(0编辑  收藏  举报