Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #define clr(x) memset((x), 0, sizeof(x))
- #define all(x) (x).begin(), (x).end()
- #define pb push_back
- #define mp make_pair
- #define in(x) int (x); input((x));
- #define x first
- #define y second
- #define fi first
- #define se second
- #define forn(i, n) for(int i = 0; i < (int)(n); ++i)
- #define ford(i, n) for(int i = (int)(n) - 1; i >= 0; --i)
- #define fore(i, a, b) for(int i = (int)(a); i <= (int)(b); ++i)
- #define for1(i, n) for(int i = 1; i <= (int)(n); ++i)
- typedef int itn;
- #define next next12345
- #define prev prev12345
- #define left lefdsf232
- #define right rig43783
- #define x1 x12345
- #define y1 y12345
- using namespace std;
- template<typename T>
- T gcd(T x, T y) {
- while (y > 0) {
- x %= y;
- swap(x, y);
- }
- return x;
- }
- template<class _T>
- inline _T sqr(const _T &x) {
- return x * x;
- }
- template<class _T>
- inline string tostr(const _T &a) {
- ostringstream os("");
- os << a;
- return os.str();
- }
- typedef long double ld;
- typedef long long ll;
- typedef long long i64;
- typedef unsigned long long ull;
- typedef unsigned long long u64;
- typedef pair<int, int> PII;
- typedef pair<int, int> pii;
- const long double PI = 3.1415926535897932384626433832795L;
- template<typename T>
- inline void input(T &a) {
- static int ed;
- a = 0;
- while (!isdigit(ed = getchar()) && ed != '-') { }
- char neg = 0;
- if (ed == '-') {
- neg = 1;
- ed = getchar();
- }
- while (isdigit(ed)) {
- a = 10 * a + ed - '0';
- ed = getchar();
- }
- if (neg) a = -a;
- }
- template<typename T = int>
- inline T nxt() {
- T res;
- input(res);
- return res;
- }
- long long mod = 1000000007;
- long long pw(long long a, long long n) {
- long long res = 1;
- while (n) {
- if (n & 1ll) {
- res = res * a % mod;
- }
- a = a * a % mod;
- n >>= 1;
- }
- return res;
- }
- long long inv(long long a) {
- return pw(a, mod - 2);
- }
- struct Edge {
- int fr, to, cap, cost, fl;
- Edge() {}
- Edge(int fr, int to, int cap, int co) : fr(fr), to(to), cap(cap), cost(co), fl(0) {}
- };
- vector<Edge> e;
- const int N = 50;
- vector<int> g[N];
- int V;
- void addEdge(int f, int t, int c, int cost) {
- g[f].push_back(e.size());
- e.push_back(Edge(f, t, c, cost));
- g[t].push_back(e.size());
- e.push_back(Edge(t, f, 0, -cost));
- }
- int u[N];
- int q[N];
- int d[N];
- int p[N];
- bool fb(int s, int t) {
- memset(d, 0x3f, V * sizeof(int));
- memset(u, 0, V * sizeof(int));
- memset(p, -1, V * sizeof(int));
- int q1 = 0, q2 = 0;
- q[q2++] = s;
- u[s] = 1;
- d[s] = 0;
- while (q1 != q2) {
- int v = q[q1++];
- u[v] = 0;
- if (q1 == V) {
- q1 = 0;
- }
- for (int eid : g[v]) {
- if (e[eid].cap - e[eid].fl <= 0)
- continue;
- int to = e[eid].to;
- int len = e[eid].cost;
- if (d[to] > d[v] + len) {
- d[to] = d[v] + len;
- p[to] = eid;
- if (!u[to]) {
- u[to] = 1;
- q[q2++] = to;
- if (q2 == V)
- q2 = 0;
- }
- }
- }
- }
- return p[t] != -1;
- }
- int flow, cost;
- void pushFlow(int s, int t) {
- flow += 1;
- cost += d[t];
- int v = t;
- while (v != s) {
- e[p[v]].fl += 1;
- e[p[v] ^ 1].fl -= 1;
- v = e[p[v]].fr;
- }
- }
- void minCostMaxFlow(int s, int t) {
- flow = 0;
- cost = 0;
- while (fb(s, t)) {
- pushFlow(s, t);
- }
- }
- void clearFlow() {
- for (int i = 0; i < e.size(); ++i) {
- e[i].fl = 0;
- }
- }
- void solve() {
- int n = nxt();
- int k = nxt();
- int c = nxt();
- int m = nxt();
- V = n + k + 2;
- int S = V - 2;
- int T = V - 1;
- int qs[m];
- int qt[m];
- int qw[m];
- for (int i = 0; i < m; ++i) {
- qs[i] = nxt() - 1;
- qt[i] = nxt() - 1;
- qw[i] = nxt();
- }
- for (int i = 0; i < m; ++i) {
- addEdge(qt[i], k + qs[i], 1, 0);
- }
- for (int i = 0; i < k; ++i) {
- addEdge(S, i, 0, 0);
- }
- for (int i = 0; i < n; ++i) {
- addEdge(k + i, T, 1, 0);
- }
- int Q = nxt();
- int dp[Q + 1];
- memset(dp, 0x3f, sizeof(dp));
- dp[0] = 0;
- int A[Q][k];
- int mask[Q];
- clr(mask);
- for (int i = 0; i < Q; ++i) {
- for (int j = 0; j < k; ++j) {
- A[i][j] = nxt();
- if (A[i][j] > 0) {
- mask[i] |= (1 << j);
- }
- }
- }
- for (int i = 0; i < Q; ++i) {
- int cm = 0;
- int AA[k];
- clr(AA);
- for (int r = i; r < Q; ++r) {
- cm |= mask[r];
- for (int j = 0; j < k; ++j) {
- AA[j] += A[r][j];
- }
- clearFlow();
- for (int j = 0; j < m; ++j) {
- e[2 * j].cost = AA[qt[j]] * qw[j];
- e[2 * j + 1].cost = -AA[qt[j]] * qw[j];
- }
- for (int j = 0; j < k; ++j) {
- if (cm & (1 << j)) {
- e[2 * m + 2 * j].cap = 1;
- } else {
- e[2 * m + 2 * j].cap = 0;
- }
- }
- int needFlow = __builtin_popcount(cm);
- minCostMaxFlow(S, T);
- if (flow != needFlow) {
- break;
- }
- dp[r + 1] = min(dp[r + 1], dp[i] + c + cost);
- }
- }
- cout << dp[Q] << "\n";
- }
- int main() {
- //#define int long
- #ifdef LOCAL
- freopen("input.txt", "r", stdin);
- //freopen("output.txt", "w", stdout);
- #else
- #define fname "race"
- //freopen(fname".in", "r", stdin);
- //freopen(fname".out", "w", stdout);
- #endif
- solve();
- #ifdef LOCAL
- cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC * 1000 << " ms." << endl;
- #endif
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement