#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <queue> using namespace std; const int maxn = 200; const int INF = 0x3f3f3f3f; int n, m, s, t; struct Edge { int from, to, flow, cap; }; struct Dinic { vector<Edge> edges; vector<int> G[maxn]; int level[maxn], cur[maxn]; void init() { edges.clear(); for (int i = 0; i < maxn; i++) G[i].clear(); } void addedge(int from, int to, int cap) { edges.push_back(Edge{from, to, 0, cap}); edges.push_back(Edge{to, from, 0, 0}); G[from].push_back(edges.size()-2); G[to].push_back(edges.size()-1); } int bfs() { memset(level, 0, sizeof(level)); level[s] = 1; queue<int> q; q.push(s); while (!q.empty()) { int u = q.front(); q.pop(); for (int i = 0; i < (int)G[u].size(); i++) { Edge &e = edges[G[u][i]]; if (e.cap - e.flow > 0 && !level[e.to]) { level[e.to] = level[u] + 1; q.push(e.to); } } } return level[t]; } int dfs(int u, int f) { if (u == t || !f) return f; for (int &i = cur[u]; i < (int)G[u].size(); i++) { Edge &e = edges[G[u][i]]; if (e.cap - e.flow > 0 && level[e.to] == level[u] + 1) { int d = dfs(e.to, min(f, e.cap - e.flow)); if (d > 0) { e.flow += d; edges[G[u][i]^1].flow -= d; return d; } } } return 0; } int maxflow() { int ans = 0, f; while (bfs()) { memset(cur, 0, sizeof(cur)); while((f = dfs(s, INF))) ans += f; } return ans; } }ac; int num[maxn], u[maxn], v[maxn], w[maxn], flag[maxn], a[maxn ], id[1010]; int main() { while (~scanf("%d%d", &n, &m)) { s = 0, t = n+50; for (int i = 1; i <= n; i++) scanf("%d", &num[i]); int cnt = 0, cnt_ = 0; for (int i = 1; i <= m; i++) { scanf("%d%d%d%d", &u[i], &v[i], &w[i], &flag[i]); if (flag[i] > 0) a[++cnt] = i; if (flag[i] < 0) id[i] = ++cnt_; } int ans = 0, cost = INF; for (int i = 0; i < (1<<cnt); i++) { int sum = 0; ac.init(); for (int j = 1; j <= n; j++) if (num[j]) ac.addedge(s, j, num[j]); for (int j = 1; j <= m; j++) { if (flag[j] < 0) { ac.addedge(u[j], id[j]+n, INF); ac.addedge(id[j]+n, v[j], INF); ac.addedge(id[j]+n, t, w[j]); } else if (flag[j] == 0) ac.addedge(u[j], v[j], INF); else ac.addedge(u[j], v[j], 1); } for (int j = 0; j < cnt; j++) { if (i & (1<<j)) { sum += w[a[j+1]]; ac.addedge(u[a[j+1]], v[a[j+1]], INF); } } int x = ac.maxflow(); if (x > ans) ans = x, cost = sum; else if (x == ans) cost = min(cost, sum); } if (ans == 0) printf("Poor Heaven Empire\n"); else printf("%d %d\n", ans, cost); } return 0; }
HDU 4309 Seikimatsu Occult Tonneru——最大流
猜你喜欢
转载自blog.csdn.net/hao_zong_yin/article/details/80151158
今日推荐
周排行