//Created by pritry
int graph[MAX][MAX]; //原图
int source; //起点,这里为0
int sink; //终点,这里为n-1
int e[MAX]; //余流
int h[MAX]; //高度
int n; //顶点数
struct Label
{
int index;
friend bool operator < (const Label& a, const Label& b)
{
return h[a.index] > h[b.index];
}
};
void Push(int u, int v)
{
int df = min(e[u], graph[u][v]);
graph[u][v] -= df;
graph[v][u] += df;
e[u] -= df;
e[v] += df;
}
void Relabel(int u)
{
int min_h = INF;
for(int i = 0; i < n; ++i)
{
if(graph[u][i] && h[i] < min_h)
{
min_h = h[i];
}
}
h[u] = min_h + 1;
}
int HLPP()
{
int i;
Label l;
priority_queue<Label> Q;
memset(e, 0, sizeof(e));
memset(h, 0, sizeof(h));
h[source] = n;
for(i = 0; i < n; ++i)
{
if(graph[source][i])
{
int df = graph[source][i];
e[source] -= df;
e[i] += df;
graph[source][i] -= df;
graph[i][source] += df;
l.index = i;
if(i != source && i != sink) Q.push(l);
}
}
while(!Q.empty())
{
l = Q.top();
Q.pop();
int u = l.index;
while(e[u])
{
for(i = 0; i < n; ++i)
if(graph[u][i] && h[u] > h[i])
break;
if(i == n) Relabel(u);
for(i = 0; i < n; ++i)
{
if(h[u] == h[i] + 1 && graph[u][i])
{
Push(u, i);
l.index = i;
if(e[i] > 0 && i != source && i != sink) Q.push(l);
}
}
}
}
return e[sink];
}