其实就是用SPFA去找增广路
跑EK就好了
vector<int> map[500];
int pre[500];
int data[105][105];
int dist[500];
bool flag[500];
int R,N;
struct Edge
{
int u,v,cap,cost;
}F[10005];
inline void addedge(int u,int v,int cap,int cost)
{
R++;map[u].push_back(R);
F[R].u=u;F[R].v=v;F[R].cap=cap;F[R].cost=cost;
R++;map[v].push_back(R);
F[R].u=v;F[R].v=u;F[R].cap=0;F[R].cost=-cost;
}
inline bool SPFA()
{
memset(dist,63,sizeof(dist));
deque<int> Q;dist[0]=0;
Q.push_back(0);flag[0]=1;
while(!Q.empty())
{
int temp=Q.at(0);Q.pop_front();
for(int i=0;i<map[temp].size();i++)
{
int num=map[temp][i];int next=F[num].v;
if(F[num].cap>0&&dist[next]>dist[temp]+F[num].cost)
{
dist[next]=dist[temp]+F[num].cost;
pre[next]=num;
if(!flag[next])
{
flag[next]=1;
Q.push_back(next);
}
}
}
flag[temp]=0;
}
if(dist[2*N+1]>10000000)
return 0;
return 1;
}
inline int min_cost_max_flow()
{
int sum=0;int MINI=INF;
while(SPFA())
{
int temp=dist[2*N+1];
int cur=2*N+1;MINI=INF;
while(cur!=0)
{
int num=pre[cur];
MINI=min(MINI,F[num].cap);
F[num].cap--;
F[num^1].cap++;
cur=F[num].u;
}
sum+=MINI*temp;
}
return sum;
}