Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<bits/stdc++.h>
- using namespace std;
- typedef long long ll;
- #define sz(s) (int)(s).size()
- #define all(s) s.begin(),s.end()
- void Speed() {
- ios_base::sync_with_stdio(false);
- cin.tie(NULL);
- }
- struct MCMF {
- struct edge {
- int to, cap, flow; ll cost;
- int backEdge;
- };
- int n, src, sink;
- vector<vector<edge>> adj;
- vector<ll> pot, dis;
- vector<int> par, from_edge;
- MCMF(int n) : n(n), adj(n + 1), pot(n + 1), dis(n + 1), par(n + 1), from_edge(n + 1) {}
- void addEdge(int u, int v, int cap, ll cost) {
- adj[u].push_back({v, cap, 0, cost, sz(adj[v])});
- adj[v].push_back({u, 0, 0, -cost, sz(adj[u]) - 1});
- }
- bool dijkstra() {
- fill(dis.begin(), dis.end(), LLONG_MAX);
- fill(par.begin(), par.end(), -1);
- dis[src] = 0;
- priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>>> pq;
- pq.emplace(0, src);
- while (!pq.empty()) {
- auto [d, u] = pq.top(); pq.pop();
- if (d > dis[u]) continue;
- for (int i = 0; i < sz(adj[u]); ++i) {
- edge &e = adj[u][i];
- if (e.flow == e.cap) continue;
- ll new_cost = e.cost + pot[u] - pot[e.to];
- if (dis[e.to] > dis[u] + new_cost) {
- dis[e.to] = dis[u] + new_cost;
- par[e.to] = u;
- from_edge[e.to] = i;
- pq.emplace(dis[e.to], e.to);
- }
- }
- }
- return dis[sink] != LLONG_MAX;
- }
- pair<int, ll> minCostMaxFlow(int _src, int _sink) {
- src = _src; sink = _sink;
- fill(pot.begin(), pot.end(), 0);
- int flow = 0;
- ll cost = 0;
- while (dijkstra()) {
- for (int i = 0; i <= n; ++i)
- if (dis[i] < LLONG_MAX) pot[i] += dis[i];
- int push = INT_MAX, cur = sink;
- while (cur != src) {
- int p = par[cur], e = from_edge[cur];
- push = min(push, adj[p][e].cap - adj[p][e].flow);
- cur = p;
- }
- cur = sink;
- while (cur != src) {
- int p = par[cur], e = from_edge[cur];
- adj[p][e].flow += push;
- adj[cur][adj[p][e].backEdge].flow -= push;
- cost += 1LL * push * adj[p][e].cost;
- cur = p;
- }
- flow += push;
- }
- return {flow, cost};
- }
- };
- void solve() {
- int n, m; cin >> n >> m;
- vector<int> a(2 * n + 1);
- for(int i = 1; i <= 2 * n; i++) cin >> a[i];
- vector<vector<array<int, 2>>> adj(2 * n + 1);
- for(int i = 0; i < m; i++){
- int u, v, w; cin >> u >> v >> w;
- adj[u].push_back({v, w});
- }
- auto dijkstra = [&](int src) -> vector<ll>{
- vector<ll> d(2 * n + 1, 1e17);
- d[src] = 0;
- priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>>> pq;
- pq.push({0, src});
- while(!pq.empty()){
- auto [c, u] = pq.top(); pq.pop();
- if(c > d[u]) continue;
- for(auto& [v, w] : adj[u]){
- if(c + w >= d[v]) continue;
- d[v] = c + w;
- pq.push({c + w, v});
- }
- }
- return d;
- };
- vector<vector<ll>> dis(2 * n + 1);
- for(int i = 1; i <= 2 * n; i++) dis[i] = dijkstra(i);
- int src = 0, sink = 2 * n + 1;
- MCMF mcmf(sink);
- for(int i = 1; i <= 2 * n; i++){
- if(i <= n) mcmf.addEdge(src, i, 1, 0);
- else mcmf.addEdge(i, sink, 1, 0);
- }
- int q; cin >> q;
- while(q--){
- int A, B, C; cin >> A >> C >> B;
- if(A > n || C <= n || dis[A][B] + dis[B][C] != dis[A][C]) continue;
- mcmf.addEdge(A, C, 1, -1LL * a[A] * (2 * n - C + 1));
- }
- auto ans = mcmf.minCostMaxFlow(src, sink);
- if(ans.first != n) return cout << "-1\n", void();
- ll res = -ans.second;
- for(int i = 1; i <= n; i++){
- res += 1LL * (2 * n - i + 1) * a[i];
- }
- cout << res << '\n';
- }
- int main() {
- Speed();
- int tc = 1;
- //cin >> tc;
- while (tc--) {
- solve();
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment