刚学费用流,求教qwq
EK改
#include<bits/stdc++.h>
using namespace std;
const int N=2e4+10,M=3e5+10,INF=1e8;
int n,m,S,T;
int head[N],ver[M],nxt[M],cc[M],ww[M],tot=0;
void add(int x,int y,int c,int d)
{
ver[tot]=y; cc[tot]=c; ww[tot]=d; nxt[tot]=head[x]; head[x]=tot++;
ver[tot]=x; cc[tot]=0; ww[tot]=-d;nxt[tot]=head[y]; head[y]=tot++;
}
int q[N],d[N],incf[N],pre[N];
bool vis[N];
inline int get(int x,int y)//x行y列
{
return (((m<<1)*x+x*x)>>1)+y;
}
bool spfa()
{
int hh=0,tt=1;
memset(d,-0x3f,sizeof d);
memset(incf,0,sizeof incf);
q[0]=S; d[S]=0; incf[S]=INF;
while(hh!=tt)
{
int x=q[hh++];
if(hh==N) hh=0;
vis[x]=0;
for(int i=head[x];~i;i=nxt[i])
{
int y=ver[i];
if(cc[i] && d[y]<d[x]+ww[i])
{
d[y]=d[x]+ww[i];
pre[y]=i;
incf[y]=min(cc[i],incf[x]);
if(!vis[y])
{
q[tt++]=y;
if(tt==N) tt=0;
vis[y]=1;
}
}
}
}
return incf[T]>0;
}
int EK()
{
int cost=0;
while(spfa())
{
int tmp=incf[T];
cost+=d[T]*tmp;
for(int i=T; i!=S; i=ver[pre[i]^1])
{
cc[pre[i]]-=tmp;
cc[pre[i]^1]+=tmp;
}
}
return cost;
}
int main()
{
scanf("%d%d",&m,&n);
memset(head,-1,sizeof head);
S=0,T=N-1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m+i-1;j++)
{
int x;
scanf("%d",&x);
int pos=get(i,j);
add(pos,605+pos,1,x);//拆点
add(605+pos,get(i+1,j),1,0);
add(605+pos,get(i+1,j+1),1,0);
if(i==1) add(S,pos,1,0);
if(i==n) add(605+pos,T,1,0);
}
}
printf("%d\n",EK());
for(int i=0;i<tot;i+=2)
{
int y=ver[i],x=ver[i^1];
if(y==605+x||y==T) cc[i]=INF,cc[i^1]=0;
else cc[i]=1,cc[i^1]=0;
}
printf("%d\n",EK());
for(int i=0;i<tot;i+=2)
{
int x=ver[i^1];
if(x!=S) cc[i]=INF,cc[i^1]=0;
else cc[i]=1,cc[i^1]=0;
}
printf("%d\n",EK());
return 0;
}