http://www.artofproblemsolving.com/blog/54262
http://blog.youkuaiyun.com/sdj222555/article/details/7841576
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <cmath>
#include <utility>
using namespace std;
#define REP(i,n) for(int i=0;i<(n);++i)
#define FOR(i,l,r) for(int i=(l);i<=(r);++i)
#define DSC(i,r,l) for(int i=(r);i>=(l);--i)
#define N 210
#define M 50000
#define INF 1e9
struct ZKW_flow
{
struct node
{
int v,f,c;
};
int st, ed, ecnt, n;
int head[N],next[M];
node edge[M];
void init()
{
memset(head, -1, sizeof(head));
ecnt = 0;
}
void add(int u, int v, int f, int c)
{
edge[ecnt].v=v;
edge[ecnt].f=f;
edge[ecnt].c=c;
next[ecnt]=head[u];
head[u]=ecnt++;
edge[ecnt].v=u;
edge[ecnt].f=0;
edge[ecnt].c=-c;
next[ecnt]=head[v];
head[v]=ecnt++;
}
int dis[N];
void SPFA()
{
for(int i=0;i<=n;i++)
dis[i]=INF;
queue<pair<int, int> > Q;
dis[st] = 0;
Q.push(make_pair(0, st));
while(!Q.empty())
{
int u=Q.front().second,
d=Q.front().first;
Q.pop();
if(dis[u] != d)
continue;
for(int i=head[u];i!=-1;i=next[i])
{
int &v =edge[i].v;
if(edge[i].f&&dis[v]>d+edge[i].c)
{
dis[v]=d+edge[i].c;
Q.push(make_pair(dis[v], v));
}
}
}
for(int i=0;i<=n;i++)
dis[i]=dis[ed]-dis[i];
}
int minCost, maxFlow;
bool use[N];
int add_flow(int u, int flow)
{
if(u == ed)
{
maxFlow += flow;
minCost += dis[st] * flow;
return flow;
}
use[u] = true;
int now = flow;
for(int i=head[u];i!=-1;i=next[i])
{
int &v =edge[i].v;
if(edge[i].f&& !use[v]&&dis[u]==dis[v]+edge[i].c)
{
int tmp = add_flow(v, min(now,edge[i].f));
edge[i].f-=tmp;
edge[i^1].f+=tmp;
now -= tmp;
if(!now) break;
}
}
return flow - now;
}
bool modify_label()
{
int d = INF;
for(int u = 0; u <= n; u++) if(use[u])
for(int i = head[u]; i!=-1; i = next[i])
{
int &v = edge[i].v;
if(edge[i].f && !use[v]) d = min(d, dis[v] + edge[i].c - dis[u]);
}
if(d == INF) return false;
for(int i = 0; i <= n; ++i) if(use[i]) dis[i] += d;
return true;
}
int min_cost_flow(int ss, int tt, int nn)
{
st = ss, ed = tt, n = nn;
minCost = maxFlow = 0;
SPFA();
while(true)
{
while(true)
{
for(int i = 0; i <= n; ++i) use[i] = 0;
if(!add_flow(st, INF)) break;
}
if(!modify_label()) break;
}
return minCost;
}
} G;
int main()
{
int n,m;
while(cin>>n>>m)
{
G.init();
int start=0,end=n;
cout<<G.min_cost_flow(start,end,end)<<endl;
}
return 0;
}