费用流(EK)

就是网络流里面的搜索变成了最短路

你跑的是\(SPFA\),所以你不能当前弧

#include<bits/stdc++.h>
#define int long long
#define F(i,i0,n) for(int i=i0;i<=n;i++)
#define Ln inline 
using namespace std;
inline int rd(){
    int f=0,x=0;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=1;ch=getchar();}
    while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
    return f?-x:x;
}
const int N=5e3+5,inf=1e9,M=5e4+5;
struct Id{
    int v,w,c,nt;
}e[M*2];
int id=1,p[N];
Ln void add(int x,int y,int z,int c){
    e[++id]={y,z,c,p[x]};
    p[x]=id;
    e[++id]={x,0,-c,p[y]};
    p[y]=id;
}
int n,m,s,t,dis[N],ans,cost;
int vis[N],pre[N];
Ln bool spfa(){
    F(i,1,n)pre[i]=0,dis[i]=inf;
    queue<int>q;
    q.push(s);
    vis[s]=1;dis[s]=0;
    while(!q.empty()){
        int x=q.front();q.pop();vis[x]=0;
        for(int i=p[x];i;i=e[i].nt){
            int v=e[i].v;
            if(e[i].w>0&&dis[v]>dis[x]+e[i].c){
                dis[v]=dis[x]+e[i].c;
                pre[v]=i;
                if(!vis[v])q.push(v),vis[v]=1;
            }
        }
    }
    if(dis[t]==inf)return 0;
    int tmp=INT_MAX;
    for(int i=pre[t];i;i=pre[e[i^1].v])tmp=min(e[i].w,tmp);
    ans+=tmp;
    cost+=dis[t]*tmp;
    for(int i=pre[t];i;i=pre[e[i^1].v])e[i].w-=tmp,e[i^1].w+=tmp;
    return 1;
}
signed main(){
    n=rd(),m=rd(),s=rd(),t=rd();
    F(i,1,m){
        int x=rd(),y=rd(),z=rd(),c=rd();
        add(x,y,z,c);
    }
    while(spfa());
    cout<<ans<<' '<<cost;
    return 0;
}
posted @ 2023-09-09 17:08  ussumer  阅读(9)  评论(0)    收藏  举报