#include using namespace std; const int maxn=3005; const int maxm=2e5+5;//至少总M*2 const int INF=0x3f3f3f3f; int TO[maxm],CAP[maxm],NEXT[maxm],tote; int FIR[maxn],gap[maxn],cur[maxn],d[maxn],q[400000],u[maxm],v[maxm],w[maxm]; int n,m,S,T; void add(int u,int v,int cap) { //printf("i=%d %d %d %d\n",tote,u,v,cap); TO[tote]=v; CAP[tote]=cap; NEXT[tote]=FIR[u]; FIR[u]=tote++; TO[tote]=u; CAP[tote]=0; NEXT[tote]=FIR[v]; FIR[v]=tote++; } void bfs() { memset(gap,0,sizeof gap); memset(d,0,sizeof d); ++gap[d[T]=1]; for(int i=1;i<=n;++i)cur[i]=FIR[i]; int head=1,tail=1; q[1]=T; while(head<=tail) { int u=q[head++]; for(int v=FIR[u];v!=-1;v=NEXT[v]) if(!d[TO[v]]) ++gap[d[TO[v]]=d[u]+1],q[++tail]=TO[v]; } } int dfs(int u,int fl) { if(u==T)return fl; int flow=0; for(int &v=cur[u];v!=-1;v=NEXT[v]) if(CAP[v]&&d[u]==d[TO[v]]+1) { int Min=dfs(TO[v],min(fl,CAP[v])); flow+=Min,fl-=Min,CAP[v]-=Min,CAP[v^1]+=Min; if(!fl)return flow; } if(!(--gap[d[u]]))d[S]=n+1; ++gap[++d[u]],cur[u]=FIR[u]; return flow; } int ISAP() { bfs(); int ret=0; while(d[S]<=n)ret+=dfs(S,INF); return ret; } void init() { tote=0; memset(FIR,-1,sizeof FIR); } int main() { srand(time(NULL)); while(scanf("%d%d",&n,&m)!=EOF) { int wage[maxn]={0}; for(int i=0;i