Codeforces Round #248 (Div. 1) D - Nanami's Power Plant 最小割
思路:类似与bzoj切糕那道题的模型。。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define PLI pair<LL, int> #define PII pair<int, int> #define SZ(x) ((int)x.size()) #define ull unsigned long long using namespace std; const int N = 21000 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 998244353; const double eps = 1e-8; const int MAX = 2e5; int head[N], level[N], tot, S, T; int n, m, a[N], b[N], c[N], L[N], R[N]; struct node { int to, w, nx; } edge[2000007]; void add(int u, int v, int w) { edge[tot].to = v; edge[tot].w = w; edge[tot].nx = head[u]; head[u] = tot++; edge[tot].to = u; edge[tot].w = 0; edge[tot].nx = head[v]; head[v] = tot++; } bool bfs() { memset(level, 0, sizeof(level)); queue<int> que; level[S] = 1; que.push(S); while(!que.empty()) { int u = que.front(); que.pop(); if(u == T) return true; for(int i = head[u]; ~i; i = edge[i].nx) { int v = edge[i].to, w = edge[i].w; if(level[v] || w <= 0) continue; level[v] = level[u] + 1; que.push(v); } } return false; } int dfs(int u, int p) { if(u == T) return p; int ret = 0; for(int i = head[u]; ~i; i = edge[i].nx) { int v = edge[i].to, w = edge[i].w; if(level[v] != level[u] + 1 || w <= 0) continue; int f = dfs(v, min(w, p - ret)); ret += f; edge[i].w -= f; edge[i ^ 1].w += f; if(ret == p) break; } if(!ret) level[u] = 0; return ret; } int Dinic() { int ans = 0; while(bfs()) ans += dfs(S, inf); return ans; } void init() { memset(head, -1, sizeof(head)); tot = 0; } inline int ID(int x, int y) { return x*208+y+102; } inline int getVal(int who, int x) { return a[who]*x*x + b[who]*x + c[who]; } int main() { init(); S = 21000, T = 0; cin >> n >> m; for(int i = 1; i <= n; i++) cin >> a[i] >> b[i] >> c[i]; for(int i = 1; i <= n; i++) { cin >> L[i] >> R[i]; add(S, ID(i, L[i]-1), inf); for(int j = L[i]; j <= R[i]; j++) add(ID(i, j-1), ID(i, j), MAX-getVal(i, j)); add(ID(i, R[i]), T, inf); } while(m--) { int u, v, d; cin >> u >> v >> d; for(int j = L[u]; j <= R[u]; j++) if(j-d>=L[v] && j-d-1<=R[v]) add(ID(u, j-1), ID(v, j-d-1), inf); } printf("%d\n", n*MAX-Dinic()); return 0; } /* */