【费用流】摘取作物(jozj 3447)
生活随笔
收集整理的這篇文章主要介紹了
【费用流】摘取作物(jozj 3447)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
正題
jozj 3447
題目大意
給你一個(gè)n*m的矩陣,每個(gè)位置有一個(gè)數(shù),每一行每一列都只能選兩個(gè)數(shù),問你所選數(shù)字之和最大是多少
解題思路
對(duì)于該矩陣,我們可以建立一個(gè)網(wǎng)絡(luò)圖(如下圖)
對(duì)于每一行建立建立一個(gè)點(diǎn)(下圖第一列),連向S,費(fèi)用為0,流量為2
對(duì)于每一列建立一個(gè)點(diǎn)(下圖第二列),連向T,費(fèi)用為0,流量為2
對(duì)于每個(gè)點(diǎn)連接相應(yīng)的行和列,費(fèi)用為該點(diǎn)的數(shù)字大小,流量為1
建好網(wǎng)絡(luò)圖后,跑最大費(fèi)用即可(注意這里不能直接跑費(fèi)用流,流量不一定最大)
該題求最大費(fèi)用,如果跑反邊,那么反邊的邊權(quán)絕對(duì)值會(huì)比上一條邊大,因?yàn)闀?huì)先跑費(fèi)用大的,所以不存在負(fù)權(quán)回路,可以用SPFA
代碼
#include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ll long long #define N 10000 using namespace std; const int inf = 1000000000; int n, m, x, w, s, t, tot, ans, v[N], vv[N], p[N], b[N], ls[N], nx[N], head[N]; queue<int>d; struct rec {int to, next, lst, val; }a[N]; void add(int x, int y, int z, int v) {a[++tot].to = y;a[tot].lst = z;a[tot].val = -v;a[tot].next = head[x];head[x] = tot;a[++tot].to = x;a[tot].lst = 0;a[tot].val = v;a[tot].next = head[y];head[y] = tot;return; } bool spfa() {memset(b, 127 / 3, sizeof(b));memset(p, 0, sizeof(p));memset(ls, 0, sizeof(ls));memset(nx, 0, sizeof(nx));while(!d.empty()) d.pop();p[s] = 1;b[s] = 0;ls[s] = inf;d.push(s);while(!d.empty()){int h = d.front();d.pop();for (int i = head[h]; i; i = a[i].next)if (b[h] + a[i].val < b[a[i].to] && a[i].lst){b[a[i].to] = b[h] + a[i].val;ls[a[i].to] = min(ls[h], a[i].lst);nx[a[i].to] = i;if (!p[a[i].to]){p[a[i].to] = 1;d.push(a[i].to);}}p[h] = 0;}return ls[t] > 0 && b[t] < 0;//保證費(fèi)用大于0(這里建立負(fù)邊跑最短路) } void dfs() {int now = t;while(nx[now]){a[nx[now]].lst -= ls[t];a[nx[now]^1].lst += ls[t];now = a[nx[now]^1].to;}ans += b[t] * ls[t];return; } int main() {scanf("%d%d", &n, &m);tot = 1;s = ++w;t = ++w;for (int i = 1; i <= n; ++i)//建圖{v[i] = ++w;add(s, v[i], 2, 0);}for (int i = 1; i <= m; ++i){vv[i] = ++w;add(vv[i], t, 2, 0);}for (int i = 1; i <= n; ++i)for (int j = 1; j <= m; ++j){scanf("%d", &x);if (!x) continue;add(v[i], vv[j], 1, x);}while(spfa())dfs();printf("%d", -ans);return 0; }總結(jié)
以上是生活随笔為你收集整理的【费用流】摘取作物(jozj 3447)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用Switch玩用Switch玩光遇
- 下一篇: 纪中A组模拟赛总结(2021.7.13)