//求上下界网络最大流,邻接表形式
//返回最大流量,-1表示无可行流,flow返回每条边的流量
//传入网络节点数n,容量mat,流量下界bf,源点source,汇点sink
//MAXN应比最大结点数多2,无可行流返回-1时mat未复原!
#define MAXN 100
#define inf 1000000000
int _max_flow(int n,int mat[][MAXN],int source,int sink,int flow[][MAXN]){
int pre[MAXN],que[MAXN],d[MAXN],p,q,t,i,j,r;
vector e[MAXN];
for (i=0;i for (e[i].clear(),j=0;j if (mat[i][j]) e[i].push_back(j),e[j].push_back(i);
for (;;){
for (i=0;i pre[t=source]=source+1,d[t]=inf;
for (p=q=0;p for (r=0;r i=e[t][r];
if (!pre[i]&&(j=mat[t][i]-flow[t][i]))
pre[que[q++]=i]=t+1,d[i]=d[t] else if (!pre[i]&&(j=flow[i][t]))
pre[que[q++]=i]=-t-1,d[i]=d[t] }
if (!pre[sink]) break;
for (i=sink;i!=source;)
if (pre[i]>0)
flow[pre[i]-1][i]+=d[sink],i=pre[i]-1;
else
flow[i][-pre[i]-1]-=d[sink],i=-pre[i]-1;
}
for (j=i=0;i return j;
}
int limit_max_flow(int n,int mat[][MAXN],int bf[][MAXN],int source,int sink,int flow[][MAXN]){
int i,j,sk,ks;
if (source==sink) return inf;
for (mat[n][n+1]=mat[n+1][n]=mat[n][n]=mat[n+1][n+1]=i=0;i for (mat[n][i]=mat[i][n]=mat[n+1][i]=mat[i][n+1]=j=0;j mat[i][j]-=bf[i][j],mat[n][i]+=bf[j][i],mat[i][n+1]+=bf[i][j];
sk=mat[source][sink],ks=mat[sink][source],mat[source][sink]=mat[sink][source]=inf;
for (i=0;i for (j=0;j _max_flow(n+2,mat,n,n+1,flow);
for (i=0;i if (flow[n][i] flow[source][sink]=flow[sink][source]=0,mat[source][sink]=sk,mat[sink][source]=ks;
_max_flow(n,mat,source,sink,flow);
for (i=0;i for (j=0;j mat[i][j]+=bf[i][j],flow[i][j]+=bf[i][j];
for (j=i=0;i return j;
}