求助最大值费用最大流
查看原帖
求助最大值费用最大流
533297
Patronus楼主2023/11/10 14:56

基本上是照着蓝书写的

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=5e4+5,M=5e5+5,delta=25;
const ll INF=(1ll<<55);
ll P[100][100],Q[100][100];
int n,m,s,t;
int head[N],ver[M],Next[M],tot;
int pre[M];
ll d[N],incf[N],edge[M],cost[M];
ll maxflow,maxcost;
bool v[N];
void add(int x,int y,ll z,ll c){
    ver[tot]=y; edge[tot]=z; Next[tot]=head[x]; cost[tot]=c; head[x]=tot++;
    ver[tot]=x; edge[tot]=0; Next[tot]=head[y]; cost[tot]=-c; head[y]=tot++;
}
bool EK_spfa(){
    memset(d,0xcf,sizeof(d));
    memset(v,0,sizeof(v));
    queue<int>q;
    q.push(s); v[s]=1; d[s]=0;
    incf[s]=INF;
    while(q.size()){
        int x=q.front();
        v[x]=0; q.pop();
        for(int i=head[x];~i;i=Next[i]){
            if(!edge[i]) continue;
            int y=ver[i];
            ll c=cost[i],z=edge[i];
            if(d[y]<d[x]+c){
                d[y]=d[x]+c;
                incf[y]=min(incf[x],z);
                pre[y]=i;
                if(!v[y]){v[y]=1; q.push(y);}
            }
        }
    }
    if(d[t]==0xcfcfcfcf) return false;
    return true;
}
void update(){
    int x=t;
    while(x!=s){
        int i=pre[x];
        edge[i]-=incf[t];
        edge[i^1]+=incf[t];
        x=ver[i^1];
    }
    maxflow+=incf[t];
    maxcost+=d[t]*incf[t];
}
int main(){
    //freopen(Name ".in", "r", stdin);
    //freopen(Name ".out", "w", stdout);
    s=0,t=2*n+1;
    memset(head,-1,sizeof(head));
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            scanf("%lld",&P[i][j]);
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            scanf("%lld",&Q[i][j]);
        }
    }
    for(int i=1;i<=n;i++){
        add(s,i,1,0);
        add(i+n,t,1,0);
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            add(i,j+n,1,P[i][j]*Q[j][i]);
        }
    }
    while(EK_spfa()) update();
    printf("%lld\n",maxcost);
    return 0;
}
2023/11/10 14:56
加载中...