#define getmin(x,y) (x= (x<0 || (y)<x)? (y):x)
struct sap{//动态邻接表
typedef int type; //流量的类型
struct edge{
int from,to;
type flow; //该条边的剩余流量
edge(int u=0,int v=0,type f=0){from=u,to=v,flow=f;}
};
int n,m; //顶点数,边数(包括反向弧)
int dis[M],cur[M]; //从起点到i的距离,当前所在的弧
int gap[M],pre[M]; //距离标号计数,可增广路上的上一条弧的序号
vector<edge>edg; //边表
vector<int>g[M]; //g[i][j]表示点i连接的第j条边的序号
void init(int _n){ //初始化
n=_n,edg.clear();
for(int i=0;i<n;i++) g[i].clear();
}
void insert(int u,int v,type c){
edg.push_back(edge(u,v,c)),edg.push_back(edge(v,u,0));
m=edg.size();
g[u].push_back(m-2),g[v].push_back(m-1);
}
type maxFlow(int s,int t){
type res=0,a;
clr(dis,0,n),clr(gap,0,n),clr(cur,0,n);
gap[0]=n;
for(int u=s;dis[s]<n;){
if(u==t){//增广
for(a=-1;u!=s;u=edg[pre[u]].from)
getmin(a,edg[pre[u]].flow);
for(u=t;u!=s;u=edg[pre[u]].from)
edg[pre[u]].flow-=a,edg[pre[u]^1].flow+=a;
res+=a;
}
bool ok=0;
for(int i=cur[u];i<g[u].size();i++){//前推
edge& e=edg[g[u][i]];
if(dis[u]==dis[e.to]+1 && e.flow>0){
pre[e.to]=g[u][i],cur[u]=i,u=e.to;
ok=1;break;
}
}
if(!ok){//回退
int mindis=n-1;
for(int i=0;i<g[u].size();i++){
edge& e=edg[g[u][i]];
if(e.flow>0 && mindis>dis[e.to])
mindis=dis[e.to],cur[u]=i;
}
if(--gap[dis[u]]==0) break;
gap[dis[u]=mindis+1]++;
if(u!=s) u=edg[pre[u]].from;
}
}
return res;
}
};
struct sap{//静态邻接表
typedef int type;
struct edge{
int v,next;
type flow;
}edg[999999]; //边表
int head[M]; //邻接表
int n,m; //顶点数,边数
int cur[M],dis[M];//当前弧,距离标号
int pre[M],gap[M];//上一点,间隙优化
void init(int _n){n=_n,m=0,clr(head,-1,n);}
void insert(int u,int v,type f,type c=0){
edg[m].flow=f,edg[m].v=v;
edg[m].next=head[u],head[u]=m++;
edg[m].flow=0,edg[m].v=u;
edg[m].next=head[v],head[v]=m++;
}
type maxFlow(int s,int t){
type res=0,a;
int i;
for(i=0;i<n;i++) cur[i]=head[i];
clr(gap,0,n),clr(dis,0,n);
gap[0]=n,pre[s]=s;
for(int u=s;dis[s]<n;){
if(u==t){
for(a=-1;u!=s;u=pre[u])
getmin(a,edg[cur[pre[u]]].flow);
for(u=t;u!=s;u=pre[u]){
edg[cur[pre[u]]].flow-=a;
edg[cur[pre[u]]^1].flow+=a;
}
res+=a;
}
bool ok=0;
for(i=cur[u];i!=-1;i=edg[i].next){
edge& e=edg[i];
if(dis[u]==dis[e.v]+1 && e.flow>0){
pre[e.v]=u,cur[u]=i,u=e.v,ok=1;
break;
}
}
if(!ok){
int mindis=n-1;
for(i=head[u];i!=-1;i=edg[i].next){
edge& e=edg[i];
if(mindis>dis[e.v] && e.flow>0)
mindis=dis[e.v],cur[u]=i;
}
if(--gap[dis[u]]==0) break;
gap[dis[u]=mindis+1]++;
u=pre[u];
}
}
return res;
}
};
struct sap{//邻接矩阵
typedef int type; //流量的类型
int n; //顶点数
type flow[M][M]; //该条边的剩余流量
int dis[M],cur[M]; //从起点到i的距离,当前所在的弧
int gap[M],pre[M]; //距离标号计数,可增广路上的上一个点
void init(int _n){ //初始化
n=_n;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
flow[i][j]=0;
}
void insert(int u,int v,double f){flow[u][v]=f;}
type maxFlow(int s,int t){
clr(dis,0,n),clr(gap,0,n),clr(cur,0,n);
gap[0]=n,pre[s]=s;
type a,res=0;
for(int u=s;dis[s]<n;){
if(u==t){
for(a=-1;u!=s;u=pre[u])
getmin(a,flow[pre[u]][u]);
for(u=t;u!=s;u=pre[u])
flow[pre[u]][u]-=a,flow[u][pre[u]]+=a;
res+=a;
}
bool ok=0;
for(int v=cur[u];v<n;v++){
if(dis[u]==dis[v]+1 && flow[u][v]>0){
pre[v]=u,cur[u]=v,u=v;
ok=1;break;
}
}
if(!ok){
int mindis=n-1;
for(int v=0;v<n;v++)
if(flow[u][v]>0 && mindis>dis[v])
mindis=dis[v],cur[u]=v;
if(--gap[dis[u]]==0) break;
gap[dis[u]=mindis+1]++,u=pre[u];
}
}
return res;
}
};