关于这一题的费用流写法
查看原帖
关于这一题的费用流写法
754746
Resolute_Faith楼主2022/7/18 10:54

时间复杂度究竟是多少啊,T了一半,剩下都是对的

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e7+6;
const int inf=1e18;
int n,cnt=1,head[N],f[N],s,t,mincost;
int dis[N],vis[N],pre[N],flow[N];
struct edge{int to,nxt,l,cst;}a[N];
void add(int x,int y,int z,int c){
    a[++cnt].to=y;
    a[cnt].nxt=head[x];
    a[cnt].l=z;
    a[cnt].cst=c;
    head[x]=cnt;
}
bool SPFA(int s,int t){
    for(register int i=s;i<=t;i++){
        dis[i]=inf;
        vis[i]=false;
        pre[i]=-1;
    }
    queue<int> q;
    dis[s]=0,vis[s]=true,pre[s]=0;
    flow[s]=inf,q.push(s);
    while(!q.empty()){
        int x=q.front();q.pop();
        vis[x]=false;
        for(register int i=head[x];i;i=a[i].nxt){
            int y=a[i].to;
            if(dis[y]>dis[x]+a[i].cst&&a[i].l>0){
                dis[y]=dis[x]+a[i].cst;
                pre[y]=i;
                flow[y]=min(flow[x],a[i].l);
                if(!vis[y]) vis[y]=true,q.push(y);
            }
        }
    }
    return dis[t]!=inf;
}
void MCMF(){
    while(SPFA(s,t)){
        int now=t;
        while(now!=s){
            int i=pre[now];
            a[i].l-=flow[t],a[i^1].l+=flow[t];
            now=a[i^1].to;
        }
        mincost+=flow[t]*dis[t];
    }
}
signed main(){
    scanf("%lld",&n);
    s=0,t=2*n+1;
    for(register int i=1;i<=n;i++) scanf("%lld",&f[i]);
    for(register int i=1;i<=n;i++){
        add(s,i,1,0);
        add(i,s,0,0);
        add(i+n,t,1,0);
        add(t,i+n,0,0);
        for(register int j=1;j<=n;j++){
            int k=abs(j-i)*(-f[i]);//建负边
            add(i,j+n,1,k);
            add(j+n,i,0,-k);
        }
    }
    MCMF();
    printf("%lld",-mincost);
}
2022/7/18 10:54
加载中...