又是一个裸的费用流板子,不再赘述。
看代码:
#include<bits/stdc++.h> using namespace std; #define int long long #define inf 1e12 const int maxn=1e5+10; int n,m,ans1,ans2; struct wll{ int beg[maxn],nex[maxn],to[maxn],w[maxn],cost[maxn],e; inline wll(){memset(beg,-1,sizeof(beg));} inline void add(int x,int y,int z,int c){ nex[e]=beg[x];beg[x]=e;to[e]=y; w[e]=z;cost[e]=c;e++; } int dis[maxn],vis[maxn],las[maxn],ed[maxn],flow[maxn]; queue<int>q; inline int spfa(){ memset(dis,0x3f,sizeof(dis)); memset(vis,0,sizeof(vis)); while(!q.empty())q.pop(); dis[0]=0;vis[0]=1;flow[0]=inf; las[n+m+1]=-1;q.push(0); while(!q.empty()){ int x=q.front(); q.pop();vis[x]=0; for(int i=beg[x];~i;i=nex[i]){ int t=to[i]; if(w[i]&&dis[t]>dis[x]+cost[i]){ dis[t]=dis[x]+cost[i]; las[t]=x;ed[t]=i; flow[t]=min(w[i],flow[x]); if(!vis[t]){ vis[t]=1;q.push(t); } } } } return las[n+m+1]!=-1; } }w1,w2; inline int read(){ int x=0,f=1;char c=getchar(); while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();} return x*f; } signed main(){ n=read(),m=read(); int x; for(int i=1;i<=n;i++){ x=read(); w1.add(0,i,x,0); w1.add(i,0,0,0); w2.add(0,i,x,0); w2.add(i,0,0,0); } for(int i=1;i<=m;i++){ x=read(); w1.add(i+n,n+m+1,x,0); w1.add(n+m+1,i+n,0,0); w2.add(i+n,n+m+1,x,0); w2.add(n+m+1,i+n,0,0); } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){ x=read(); w1.add(i,j+n,inf,x); w1.add(j+n,i,0,-x); w2.add(i,j+n,inf,-x); w2.add(j+n,i,0,x); } while(w1.spfa()){ ans1+=w1.dis[n+m+1]*w1.flow[n+m+1]; int tmp=n+m+1; while(tmp){ w1.w[w1.ed[tmp]]-=w1.flow[n+m+1]; w1.w[w1.ed[tmp]^1]+=w1.flow[n+m+1]; tmp=w1.las[tmp]; } } while(w2.spfa()){ ans2-=w2.dis[n+m+1]*w2.flow[n+m+1]; int tmp=n+m+1; while(tmp){ w2.w[w2.ed[tmp]]-=w2.flow[n+m+1]; w2.w[w2.ed[tmp]^1]+=w2.flow[n+m+1]; tmp=w2.las[tmp]; } } printf("%lld %lld ",ans1,ans2); return 0; }
就是打代码有点心累。
深深地感到自己的弱小。