//多路增广
bool Dinic_bfs( int st )
{
queue<int>que;
for( int i = 0; i <= n; i ++ )
dis[i] = -1;
dis[st] = 0;
que.push(st);
while( !que.empty() ){
int u = que.front(); que.pop();
for( int i = head[u]; i != -1; i = edge[i].next ){
node v = edge[i];
if( v.w && dis[v.v] == -1 ){
dis[v.v] = dis[u] + 1;
que.push(v.v);
if( v.v == n )
return true;
}
}
}
return false;
}
int Dinic_dfs( int u,int maxf )
{
if( u == n )
return maxf;
int ans = 0, flow;
for( int i = head[u]; i != -1 && ans < maxf; i = edge[i].next ){
if( edge[i].w && dis[edge[i].v] == dis[u] + 1 ){
if( flow = Dinic_dfs( edge[i].v,mins(edge[i].w,maxf-ans) )){
edge[i].w -= flow;
edge[i^1].w += flow;
ans += flow;
}
}
}
if( !ans )//关键的一句话
dis[u] = -1;
return ans;
}
int Dinic( int st,int end )
{
int ans = 0,flow;
while( Dinic_bfs(st) ){
while( flow = Dinic_dfs( st,inf ) ) //增广
ans += flow;
}
return ans;
}
int Dinic(int sta, int end)
{
int max = 0;
int i, k, curr;
while(true)
{
memset(level, -1, sizeof(level));
int f, r;
f = 0; r = 1;
que[0] = sta;
level[sta] = 0;
while(f < r)
{
curr = que[f++];
for(i = head[curr]; i; i = edges[i].next)
if(edges[i].c && level[k = edges[i].v] == -1)
{
level[k] = level[curr] + 1;
que[r++] = k;
if(k == end){ f = r; break; }
}
}
if(level[end] == -1) break;
memcpy(temp, head, sizeof(temp));
int top;
for(curr = sta, top = 0; ;)
{
if(curr == end)
{
int tp = inf;
for(i = 0; i < top; i++)
if(tp > edges[que[i]].c)
tp = edges[que[f = i]].c;
for(i = 0; i < top; i++)
{
edges[que[i]].c -= tp;
edges[que[i]^1].c += tp;
}
top = f;
max += tp; curr = edges[que[top-1]].v;
}
for(i = temp[curr]; temp[curr]; i = temp[curr] = edges[temp[curr]].next)
if(edges[i].c && level[edges[i].v] == level[curr] + 1)
break;
if(temp[curr])
{
que[top++] = temp[curr];
curr = edges[temp[curr]].v;
}
else
{
if(top == 0) break;
level[curr] = -1;
if((top--) == 1)
curr = sta;
else
curr = edges[head[top-1]].v;
}
}
}
return max;
}