최대 흐름, 최소 비용 최대 흐름 【 템 플 릿 】
최대 스 트림 템 플 릿: (제목 링크)
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
#define N 1200
#define M 50220
#define INF 0x3f3f3f3f
class MaxFlow {
public:
struct record {
int v, f, next;
} edge[M];
int n, s, t;
int pos[N], dis[N], vh[N], cl;
int his[N], di[N], pre[N];
void AddEdge(int a, int b, int f) {
cl++;
edge[cl].next = pos[a];
edge[cl].v = b;
edge[cl].f = f;
pos[a] = cl;
cl++;
edge[cl].next = pos[b];
edge[cl].v = a;
edge[cl].f = 0; // , f = f
pos[b] = cl;
}
void Init() {
cl = 1;
memset(dis, 0, sizeof(dis));
memset(vh, 0, sizeof(vh));
memset(pos, 0, sizeof(pos));
}
int flow() {
vh[0] = n; // GAP ( 0, 0 n)
for (int i = 0; i < n; i++) di[i] = pos[i]; //
int i = s, aug = INF, flow = 0; // ,flow ,aug
bool flag = false; // , ( )
while (dis[s] < n) {
his[i] = aug; //
flag = false;
for (int p=di[i]; p; p=edge[p].next)
if ((edge[p].f > 0) && (dis[edge[p].v] + 1 == dis[i])) {//
flag = true; //
di[i] = p; //
aug = min(aug, edge[p].f); //
pre[edge[p].v] = p; //
i = edge[p].v; //
if (i == t) {// ,
flow += aug; //
while (i != s) {// ,
edge[pre[i]].f -= aug;
edge[pre[i]^1].f += aug;
i = edge[pre[i]^1].v;
}
aug = INF;
}
break;
}
if (flag) continue; // ,
int min = n - 1;
for (int p=pos[i]; p; p=edge[p].next)
if ((edge[p].f > 0) && (dis[edge[p].v] < min)) {
di[i] = p; //
min = dis[edge[p].v];
}
--vh[dis[i]];
if (vh[dis[i]] == 0) break; // vh , , (GAP )
dis[i] = min + 1;
++vh[dis[i]];
if (i != s) {//
i = edge[pre[i]^1].v;
aug = his[i];
}
}
return flow;
}
} net;
int n, b, g[1002][22], s[22];
void init(int x, int y) {
net.Init();
net.s = 0, net.t = n+b+1, net.n = n+b+2;
for (int i=1; i<=n; i++) net.AddEdge(0, i, 1);
for (int i=1; i<=n; i++) for (int j=x; j<=y; j++)
net.AddEdge(i, g[i][j]+n, 1);
for (int i=1; i<=b; i++) net.AddEdge(n+i, net.t, s[i]);
}
int main() {
scanf("%d%d", &n, &b);
for (int i=1; i<=n; i++) for (int j=1; j<=b; j++) scanf(" %d", &g[i][j]);
for (int i=1; i<=b; i++) scanf("%d", &s[i]);
int ans = INF;
for (int i=1; i<=b; i++) for (int j=i; j<=b; j++) {
init(i, j);
if (net.flow() == n) ans = min(ans, j-i+1);
}
printf("%d
", ans);
return 0;
}
/*
*
* (SPFA)
* O(Maxflow(G)*kV)
* HIT_ACM 2012 Summer Camp
* by xiaodai
*/
#include <iostream>
#include <queue>
#include <cstring>
#include <cstdio>
#define SETZR(a) memset(a,0,sizeof(a))
using namespace std;
const int maxn = 10000;
const int maxm = 1000000;
const int INF = 1000000000;
struct record {
int v, f, c, next;
} edge[maxm];
int cas, ans, cl, n, m, s, t, aug, k, p;
int dist[maxn], pre[maxn], pointer[maxn];
bool vis[maxn];
queue<int> q;
void connect(int a, int b, int f, int c) {
cl++;
edge[cl].next = pointer[a];
edge[cl].v = b;
edge[cl].f = f;
edge[cl].c = c;
pointer[a] = cl;
cl++;
edge[cl].next = pointer[b];
edge[cl].v = a;
edge[cl].f = 0;
edge[cl].c = -c;
pointer[b] = cl;
}
bool spfa() {
memset(vis, 0, sizeof (vis));
for (int i = 0; i < n; i++) dist[i] = INF;
q.push(s);
dist[s] = 0;
pre[s] = 0;
while (!q.empty()) {
k = q.front();
q.pop();
vis[k] = 0;
for (p=pointer[k]; p; p=edge[p].next)
if ((edge[p].f > 0) && (edge[p].c + dist[k] < dist[edge[p].v])) {
dist[edge[p].v] = edge[p].c + dist[k];
pre[edge[p].v] = p;
if (!vis[edge[p].v]) {
q.push(edge[p].v);
vis[edge[p].v] = 1;
}
}
}
if (dist[t] == INF) return false;
aug = INF;
for (p=re[t]; p; p=pre[edge[p^1].v])
aug = min(aug, edge[p].f);
for (p=pre[t]; p; p=pre[edge[p^1].v]) {
edge[p].f -= aug;
edge[p^1].f += aug;
}
ans += dist[t] * aug;
return true;
}
int main() {
scanf("%d", &cas);
while (cas--) {
cl = 1;
scanf("%d%d%d%d", &n, &m, &s, &t);
SETZR(pointer);
for (int i = 0; i < m; i++) {
int p, k, f, c;
scanf("%d%d%d%d", &p, &k, &f, &c);
connect(p, k, f, c);
}
ans = 0;
while (spfa()) ;
printf("%d
", ans);
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Docker를 사용한 React 및 .NET Core 6.0 샘플 프로젝트 - 1부이 기사에서는 Entity Framework Core Code First 접근 방식을 사용하는 ASP.NET Core 6.0 WEP API의 CRUD(만들기, 읽기, 업데이트 및 삭제) 작업에 대해 설명합니다. 웹 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.