题目:https://www.luogu.org/problemnew/show/P4014
最大/小费用最大流裸题。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; queue<int>q; int const inf=1e9; int n,t,head[205],ct=1,pre[205],mx,mn,incf[205],dis[205]; bool vis[205]; struct N{ int hd,to,next,w,v; N(int h=0,int t=0,int n=0,int w=0,int v=0):hd(h),to(t),next(n),w(w),v(v) {} }edge[15005],tmp[15005]; bool spfa() { memset(dis,-2,sizeof dis); memset(incf,0x3f,sizeof incf); memset(vis,0,sizeof vis); memset(pre,0,sizeof pre); while(q.size())q.pop(); dis[0]=0;vis[0]=1;q.push(0); while(q.size()) { int x=q.front();q.pop();vis[x]=0; for(int i=head[x];i;i=edge[i].next) { int u=edge[i].to; if(dis[u]<dis[x]+edge[i].w&&edge[i].v) { dis[u]=dis[x]+edge[i].w; pre[u]=i; incf[u]=min(incf[x],edge[i].v); if(!vis[u])vis[u]=1,q.push(u); } } } return pre[t]; } bool spfa2() { memset(dis,0x3f,sizeof dis); memset(incf,0x3f,sizeof incf); memset(vis,0,sizeof vis); memset(pre,0,sizeof pre); while(q.size())q.pop(); dis[0]=0;vis[0]=1;q.push(0); while(q.size()) { int x=q.front();q.pop();vis[x]=0; for(int i=head[x];i;i=tmp[i].next) { int u=edge[i].to; if(dis[u]>dis[x]+tmp[i].w&&tmp[i].v) { dis[u]=dis[x]+tmp[i].w; pre[u]=i; incf[u]=min(incf[x],tmp[i].v); if(!vis[u])vis[u]=1,q.push(u); } } } return pre[t]; } void mcf() { memcpy(tmp,edge,sizeof edge); while(spfa()) { mx+=incf[t]*dis[t]; for(int i=pre[t];i;i=pre[edge[i].hd]) { edge[i].v-=incf[t]; edge[i^1].v+=incf[t]; } } while(spfa2()) { mn+=incf[t]*dis[t]; for(int i=pre[t];i;i=pre[edge[i].hd]) { tmp[i].v-=incf[t]; tmp[i^1].v+=incf[t]; } } } int main() { scanf("%d",&n); t=2*n+2; for(int i=1;i<=n;i++) { edge[++ct]=(N){0,i,head[0],0,1};head[0]=ct; edge[++ct]=(N){i,0,head[i],0,0};head[i]=ct; } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { int x; scanf("%d",&x); edge[++ct]=(N){i,j+n,head[i],x,1};head[i]=ct; edge[++ct]=(N){j+n,i,head[j+n],-x,0};head[j+n]=ct; } for(int j=1;j<=n;j++) { edge[++ct]=(N){j+n,t,head[j+n],0,1};head[j+n]=ct; edge[++ct]=(N){t,j+n,head[t],0,0};head[t]=ct; } mcf(); printf("%d\n%d",mn,mx); return 0; }