网络流

发布时间 2023-07-19 14:41:00作者: yisiwunian

费用流

#include<bits/stdc++.h>
using namespace std;
const int MAX=210010;
const int inf=1<<28;
int n,m,s,t,tot,head[410],x,y,z;
int dis[MAX],pre[MAX],vis[MAX],ans,cost,flo[MAX];
struct edge{
    int t,nxt,flow,val;
} e[MAX];
inline int read(){
    int x=0,f=1;char c=getchar();
    while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c^48);c=getchar();}
    return x*f;
}
inline void add(int,int,int,int);
inline bool spfa();
inline void EK();
int main(){
    n=read();m=read();s=1;t=n;
    for(int i=2;i<n;++i)  add(i,n+i,1,0);
    for(int i=1;i<=m;++i){
        x=read();y=read();z=read();
        if(x!=1)  x+=n;add(x,y,1,z);
    }EK();
}
inline void add(int a,int b,int c,int v){
    e[++tot].t=b;e[tot].flow=c;e[tot].val=v;
    e[tot].nxt=head[a];head[a]=tot;
    e[++tot].t=a;e[tot].flow=0;e[tot].val=-v;
    e[tot].nxt=head[b];head[b]=tot;
}
inline bool spfa(){
    for(int i=1;i<2*n;++i)  vis[i]=0,dis[i]=inf;
    vis[s]=1;dis[s]=0;pre[t]=-1;flo[s]=dis[t];
    queue<int>q;q.push(s);
    while(!q.empty()){
        int u=q.front();q.pop();
        vis[u]=0;
        for(int i=head[u];i;i=e[i].nxt){
            int v=e[i].t;
            if(dis[v]>dis[u]+e[i].val&&e[i].flow){
                flo[v]=min(flo[u],e[i].flow);
                pre[v]=i;dis[v]=dis[u]+e[i].val;
                if(!vis[v]){
                    vis[v]=1;q.push(v);
                }
            }
        }
    }return dis[t]!=flo[s];
}inline void EK(){
    while(spfa()){
        ans+=flo[t];cost+=flo[t]*dis[t];
        int now=t;
        while(now!=s){
            e[pre[now]].flow-=flo[t];
            e[((pre[now]-1)^1)+1].flow+=flo[t];
            now=e[((pre[now]-1)^1)+1].t;
        }
    }printf("%d %d\n",ans,cost);
}