Create a new position for the network flow of the WordPress 11765 Component Placement, 11765 placement
Question link: Click the open link
Question:
Given n items and m Constraints
Divide n items into two sets
The first line below indicates the cost of dividing an I item into the first set.
The second row indicates the cost to the second set.
The third row indicates the limit on items (1 indicates that items can only be grouped into the first set,-1 indicates that items can only be grouped into the second set, and 0 indicates no limit)
The following m rows provide constraints
U v cost indicates that u v must communicate with each other. If the two points are already in the same set, the cost is 0. If they are not in the same set, the cost is increased by cost.
Question: minimum cost under m Constraints
Ideas:
First, I think it's a network stream. = It's hard to figure out
Use traffic to represent the cost
1. If I is placed in the first set, an edge with a traffic of a [I] will be connected to the source point, if it is placed in the second set, an edge with a traffic of B [I] will be connected to the sink.
This minimizes the cost of placing a point in any set.
2. If the constraints are met, a undirected edge is connected to u and v, and the traffic is cost.
If u and v are bound by the third row in the same set, the traffic cannot be increased when this edge is added, that is, the fee is increased by 0.
Cost is bound to different sets.
Orz
# Include <stdio. h> # include <string. h> # include <iostream> # include <math. h> # include <algorithm> # include <queue> # include <vector> using namespace std; # define ll long # define N 100040 # define M 205000 # define inf 107374182 # define inf64 1152921504606846976 struct Edge {ll from, to, cap, nex ;} edge [M * 2]; // note that this must be large enough. Otherwise, re will have reverse arc ll head [N], edgenum; void add (ll u, ll v, ll cap, ll rw = 0) {// if it is a directed edge, then: add (u, v, cap); if it is Undirected Edge: add (u, v, cap, cap); edge E = {u, v, cap, head [u]}; Edge [edgenum] = E; head [u] = edgenum ++; Edge E2 = {v, u, rw, head [v]}; edge [edgenum] = E2; head [v] = edgenum ++;} ll sign [N]; bool BFS (ll from, ll to) {memset (sign,-1, sizeof (sign )); sign [from] = 0; queue <ll> q; q. push (from); while (! Q. empty () {ll u = q. front (); q. pop (); for (ll I = head [u]; I! =-1; I = edge [I]. nex) {ll v = edge [I]. to; if (sign [v] =-1 & edge [I]. cap) {sign [v] = sign [u] + 1, q. push (v); if (sign [to]! =-1) return true ;}}return false;} ll Stack [N], top, cur [N]; ll Dinic (ll from, ll) {ll ans = 0; while (BFS (from, to) {memcpy (cur, head, sizeof (head); ll u = from; top = 0; while (1) {if (u = to) {ll flow = inf, loc; // loc indicates the minimum cap edge in the Stack for (ll I = 0; I <top; I ++) if (flow> edge [Stack [I]. cap) {flow = edge [Stack [I]. cap; loc = I ;}for (ll I = 0; I <top; I ++) {edge [Stack [I]. cap-= flow; edge [Stack [I] ^ 1]. cap + = flow;} ans + = flow; top = loc; u = edge [Stack [top]. from;} for (ll I = cur [u]; I! =-1; cur [u] = I = edge [I]. nex) // cur [u] indicates the subscript if (edge [I] of the edge where the u is located. cap & (sign [u] + 1 = sign [edge [I]. to]) break; if (cur [u]! =-1) {Stack [top ++] = cur [u]; u = edge [cur [u]. to;} else {if (top = 0) break; sign [u] =-1; u = edge [Stack [-- top]. from ;}}return ans;} void init () {memset (head,-1, sizeof head); edgenum = 0;} ll n, m; ll a [N], B [N], c [N]; void input () {ll u, v, cos; cin> n> m; init (); for (ll I = 1; I <= n; I ++) scanf ("% lld", & a [I]); for (ll I = 1; I <= n; I ++) scanf ("% lld", & B [I]); for (ll I = 1; I <= n; I ++) scanf ("% lld", & c [I]);} void work () {ll from = 0, to = n + 10, u, v, cos; for (ll I = 1; I <= n; I ++) {if (c [I] = 1) add (from, I, a [I]), add (I, to, inf); else if (c [I] =-1) add (from, I, inf), add (I,, B [I]); else add (from, I, a [I]), add (I, to, B [I]);} while (m --) {scanf ("% lld", & u, & v, & cos); add (u, v, cos); add (v, u, cos) ;}cout <Dinic (from, to) <endl ;}int main () {int T; cin >>t; while (T --) {input (); work ();} return 0 ;}