求助dinic最小费用最大流
查看原帖
求助dinic最小费用最大流
597004
IRIDESCENTqwq楼主2024/7/12 12:53
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
const int MAXN = 1e6;
int n, m, p[41], sum, t[41][101], x[MAXN], y[MAXN];
struct Edge{
	int u, v, w, c, nxt;
}e[MAXN];
int head[MAXN], ind[MAXN], cnt = 1;
void addEdge(int u, int v, int w, int c){
	e[++cnt] = (Edge){u, v, w, c, head[u]};
	head[u] = cnt;
}
void add(int u, int v, int w, int c){
	addEdge(u, v, w, c);
	addEdge(v, u, 0, -c);
}
int id[101][801], cur, S = 0, T = 1;
//id[i][j]: 第i位厨师的倒数第j道菜 
//0: S
//n+1: T
//1~n: 菜种 
//n+2~: (厨师)动态加点 
int newdish(int i, int j){
	cur++;
	x[cur] = i, y[cur] = j;
	add(S, cur, 1, 0);
	for (int k = 1; k <= n; k++){
		add(cur, k, 1, t[k][i] * j);
	}
	return cur;
}
void init(){
	S = 0, T = n + 1;
	for (int i = 1; i <= n; i++){
		add(i, T, p[i], 0);
	}
	cur = n + 1;
	for (int i = 1; i <= m; i++){
		id[i][1] = newdish(i, 1);
	}
}
int d[MAXN];
bool vis[MAXN];
queue<int> q;
bool spfa(){
	memcpy(ind, head, sizeof head);
	memset(d, 0x3f, sizeof d);
	memset(vis, false, sizeof vis);
	d[S] = 0;
	q.push(S);
	vis[S] = true;
	while (!q.empty()){
		int u = q.front();
		q.pop();
		vis[u] = false;
		for (int i = head[u]; i; i = e[i].nxt){
			int v = e[i].v, c = e[i].c;
			if (e[i].w > 0 && d[u] + c < d[v]){
				d[v] = d[u] + c;
				if (!vis[v]){
					vis[v] = true;
					q.push(v);
				}
			}
		}
	}
	return d[T] != INF;
}
int ans = 0;
int dfs(int u, int lim){
    if (u >= n + 2){
        int xx = x[u], yy = y[u] + 1;
        if (!id[xx][yy] && yy <= sum)
            id[xx][yy] = newdish(xx, yy);
    }
	if (u == T) return lim;
	int flow = 0;
	vis[u] = true;
	for (; ind[u]; ind[u] = e[ind[u]].nxt){
		Edge t = e[ind[u]];
		if (!vis[t.v] && t.w > 0 && d[t.v] == d[u] + t.c){
			int delta = dfs(t.v, min(lim - flow, t.w));
			if (!delta) d[t.v] = -1;
			e[ind[u]].w -= delta, e[ind[u] ^ 1].w += delta;
			flow += delta;
			ans += delta * t.c;
			if (flow == lim) break;
		}
	}
	return flow;
}
void mcmf(){
	while (spfa()){
		memset(vis, false, sizeof vis);
		dfs(S, INF);
	}
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	cin >> n >> m;
	for (int i = 1; i <= n; i++){
		cin >> p[i];
		sum += p[i];
	}
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
			cin >> t[i][j];
	init();
	mcmf();
	cout << ans << endl;
	return 0;
}
2024/7/12 12:53
加载中...