牛客暑假多校第二场 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 }