费用流 ZOJ 3933 Team Formation
生活随笔
收集整理的這篇文章主要介紹了
费用流 ZOJ 3933 Team Formation
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?
題目鏈接
題意:兩個隊伍,有一些邊相連,問最大組對數以及最多女生數量
分析:費用流模板題,設置兩個超級源點和匯點,邊的容量為1,費用為男生數量.建邊不能重復建邊否則會T.zkw費用流在稠密圖跑得快,普通的最小費用最大流也能過,只是相對來說慢了點.
#include <bits/stdc++.h>const int N = 5e2 + 5; const int INF = 0x3f3f3f3f; struct Min_Cost_Max_Flow {struct Edge {int from, to, cap, flow, cost;};std::vector<Edge> edges;std::vector<int> G[N];bool vis[N];int d[N], p[N], a[N];int n, m;void init(int n) {this->n = n;for (int i=0; i<=n; ++i) {G[i].clear ();}edges.clear ();}void add_edge(int from, int to, int cap, int cost) {edges.push_back ((Edge) {from, to, cap, 0, cost});edges.push_back ((Edge) {to, from, 0, 0, -cost});m = edges.size ();G[from].push_back (m - 2);G[to].push_back (m - 1);}bool SPFA(int s, int t, int &flow, int &cost) {memset (d, INF, sizeof (d));memset (vis, false, sizeof (vis));memset (p, -1, sizeof (p));d[s] = 0; vis[s] = true; p[s] = 0; a[s] = INF;std::queue<int> que; que.push (s);while (!que.empty ()) {int u = que.front (); que.pop ();vis[u] = false;for (int i=0; i<G[u].size (); ++i) {Edge &e = edges[G[u][i]];if (e.cap > e.flow && d[e.to] > d[u] + e.cost) {d[e.to] = d[u] + e.cost;p[e.to] = G[u][i];a[e.to] = std::min (a[u], e.cap - e.flow);if (!vis[e.to]) {vis[e.to] = true;que.push (e.to);}}}}if (d[t] == INF) {return false;}flow += a[t];cost += d[t] * a[t];int u = t;while (u != s) {edges[p[u]].flow += a[t];edges[p[u]^1].flow -= a[t];u = edges[p[u]].from;}return true;}void run(int s, int t, int &flow, int &cost) {flow = cost = 0;while (SPFA (s, t, flow, cost));printf ("%d %d\n", flow, 2 * flow - cost);for (int i=0; i<edges.size (); i+=2) {if (edges[i].from == s || edges[i].to == t || edges[i].flow == 0) {continue;}printf ("%d %d\n", edges[i].from, edges[i].to);}} }; Min_Cost_Max_Flow mcmf; char group[N], sex[N]; bool list[N]; int n, m;int main() {int T; scanf ("%d", &T);while (T--) {scanf ("%d", &n);scanf ("%s", group + 1);scanf ("%s", sex + 1);mcmf.init (n + 1);int s = 0, t = n + 1;for (int i=1; i<=n; ++i) {if (group[i] == '0') {mcmf.add_edge (s, i, 1, 0);} else {mcmf.add_edge (i, t, 1, 0);}int m; scanf ("%d", &m);memset (list, false, sizeof (list));for (int j=1; j<=m; ++j) {int v; scanf ("%d", &v);list[v] = true;}if (group[i] == '1') {continue;}int cost = (sex[i] == '1');for (int j=1; j<=n; ++j) {if (list[j] || group[i] == group[j]) {continue;}mcmf.add_edge (i, j, 1, cost + (sex[j] == '1'));}}int flow, cost;mcmf.run (s, t, flow, cost);}return 0; }
轉載于:https://www.cnblogs.com/Running-Time/p/5387367.html
總結
以上是生活随笔為你收集整理的费用流 ZOJ 3933 Team Formation的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: is_array
- 下一篇: shell 删除奇数偶数行