https://loj.ac/problem/6011
最大费用最大流
最小费用最大流
#include <bits/stdc++.h> using namespace std; const int maxn = 300; const int inf = 0x3f3f3f3f; int n,m; int ck(int x){ return x; } int ls(int x){ return m+x; } int head[maxn]; int tot =0; struct edge{ int v,nex,w,c; }e[maxn*maxn]; void addedge(int u,int v,int w,int c){ e[tot] = (edge){v,head[u],w,c}; head[u] = tot++; e[tot] = (edge){u,head[v],0,-c}; head[v] = tot++; } int vis[maxn]; int dis[maxn]; int pre[maxn]; bool spfa(int S,int T){ memset(dis,0x3f,sizeof(dis)); memset(vis,0,sizeof(vis)); queue<int> q; vis[S] = 1; q.push(S); dis[S] = 0; while(!q.empty()){ int now = q.front(); q.pop(); vis[now] = 0; for(int i=head[now];i!=-1;i=e[i].nex){ int w = e[i].w; int c = e[i].c; int v = e[i].v; if(w>0 && dis[v]>dis[now]+c){ dis[v] = dis[now]+c; pre[v] = i; if(vis[v]==0){ vis[v] = 1; q.push(v); } } } } return dis[T]==0x3f3f3f3f?false:true; } int ed(int S,int T,int &maxflow){ int ret = 0; int flow = 0x3f3f3f3f; int p; for(int i=T;i!=S;i=e[p^1].v){ p = pre[i]; flow = min(flow,e[p].w); } for(int i=T;i!=S;i=e[p^1].v){ p = pre[i]; ret+=flow*e[p].c; e[p].w-=flow; e[p^1].w+=flow; } maxflow+=flow; return ret; } void solve(int S,int T,int k){ int maxflow = 0; int ans = 0; while(spfa(S,T)){ ans+=ed(S,T,maxflow); } printf("%d\n",ans*k); } int aa[maxn],bb[maxn],cc[maxn][maxn]; void solve2(int S,int T){ memset(head,-1,sizeof(head)); tot = 0; for(int i=1;i<=m;i++){ int t = aa[i]; addedge(S,ck(i),t,0); } for(int i=1;i<=n;i++){ int t=bb[i]; addedge(ls(i),T,t,0); } for(int i=1;i<=m;i++){ for(int j=1;j<=n;j++){ int t=cc[i][j]; addedge(ck(i),ls(j),inf,-t); } } solve(S,T,-1); } int main() { memset(head,-1,sizeof(head)); scanf("%d%d",&m,&n); int S = 0; int T = m+n+1; for(int i=1;i<=m;i++){ int t; scanf("%d",&t); aa[i] = t; addedge(S,ck(i),t,0); } for(int i=1;i<=n;i++){ int t;scanf("%d",&t); bb[i] = t; addedge(ls(i),T,t,0); } for(int i=1;i<=m;i++){ for(int j=1;j<=n;j++){ int t; scanf("%d",&t); cc[i][j] = t; addedge(ck(i),ls(j),inf,t); } } solve(S,T,1); solve2(S,T); return 0; }