Home Codeforces - 321B 最大费用流
Post
Cancel

Codeforces - 321B 最大费用流

MCMF 必须是满足流量最大为前提下的最小费用流 (这里是最大费用流)

因此还必须不断地枚举 m 的流量才行

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxn = 1e5+11;
const int oo = 0x3f3f3f3f;
int to[maxn<<1],cost[maxn<<1],cap[maxn<<1],flow[maxn<<1],nxt[maxn<<1];
int head[maxn],tot;
void init(){
    memset(head,-1,sizeof head);
    tot=0;
}
void add(int u,int v,int c,int w){
    to[tot]=v;
    cap[tot]=c;
    flow[tot]=0;
    cost[tot]=w;
    nxt[tot]=head[u];
    head[u]=tot++;
    swap(u,v);
    to[tot]=v;
    cap[tot]=0;
    flow[tot]=0;
    cost[tot]=-w;
    nxt[tot]=head[u];
    head[u]=tot++;
}
struct QUEUE{
    int que[maxn];
    int front,rear;
    void init(){front=rear=0;}
    void push(int x){que[rear++]=x;}
    int pop(){return que[front++];}
    bool empty(){return front==rear;}
}que;
int n,m,s,t;
int dis[maxn],pre[maxn];
bool vis[maxn];
bool spfa(){
	que.init();
	memset(dis,0x80,sizeof dis);
	memset(vis,0,sizeof vis);
	memset(pre,-1,sizeof pre);
	que.push(s);dis[s]=0;vis[s]=1;
	while(!que.empty()){
		int u = que.pop();
		vis[u]=0;
		for(int i = head[u]; ~i; i = nxt[i]){
			int v=to[i],c=cap[i],f=flow[i],w=cost[i];
			if(c>f&&dis[v]<dis[u]+w){
				dis[v]=dis[u]+w;
				pre[v]=i;
				if(!vis[v]){
					vis[v]=1;
					que.push(v);
				}
			}
		}
	}
	if(pre[t]==-1)return 0;
	return 1;
}
int mcmf(){
	int mc=0,mf=0;
	while(spfa()){
		int mn=oo;
		for(int i = pre[t]; ~i; i = pre[to[i^1]]){
			mn=min(mn,cap[i]-flow[i]);
		}
		for(int i = pre[t]; ~i; i = pre[to[i^1]]){
			flow[i]+=mn;
			flow[i^1]-=mn;
			mc+=cost[i]*mn;
		}
		mf+=mn;
	}
	return mc;
}
int n1,n2,n3,a[maxn],b[maxn],atr[maxn],x;
char str[199];
int main(){
	while(scanf("%d%d",&n1,&n2)!=EOF){
		init();
		if(n1<n2){
			n3=n2-n1;
			n=2*n2+2;
			t=n;s=t-1;
		}
		else{
			n3=0;
			n=n1+n2+2;
			t=n;s=n-1;	
		}
		for(int i = 1; i <= n1; i++){
			scanf("%s%d",str,&a[i]); 
			if(str[0]=='A') atr[i]=1;
			else atr[i]=0;
		}
		for(int i = 1; i <= n2; i++){
			scanf("%d",&b[i]);
		}
		if(n3) for(int i = 1; i <= n3; i++){
			atr[i+n1]=1;
			a[i+n1]=0;
		}
		for(int i = 1; i <= n2; i++){
			add(s,i,1,0);
		}
		for(int i = 1; i <= n1+n3; i++){
			add(i+n2,t,1,0);
		}
		for(int i = 1; i <= n2; i++){
			for(int j = 1; j <= n1+n3; j++){
				if(atr[j]==1){
					if(b[i]>=a[j]){
						if(a[j]!=-oo) add(i,j+n2,1,b[i]-a[j]);
						else add(i,j+n2,1,b[i]);
					}
					else add(i,j+n2,1,-9999);
				}
				else{
					if(b[i]>a[j]){
						add(i,j+n2,1,0);
					}
					else add(i,j+n2,1,-9999);
				}
			}
		} 
		printf("%d\n",mcmf());
	}
    return 0;
}
This post is licensed under CC BY 4.0 by the author.