#include using namespace std; typedef long long ll; typedef pair PII; const int MAXN = 1e6 + 10; const int MM = 1e9 + 7; // 通用网络流(Sap + Johnson + 上下界) By 猛犸也钻地 @ 2012.02.10 #include #include #include using namespace std; class Network { public: typedef int VAL; static const int SIZE = 100; static const int INF = 1000000007; typedef struct ARC{int t,c; VAL w; ARC* o;}* PTR; ARC arc[10000]; PTR now[SIZE],e[SIZE]; int cnt[SIZE],l[SIZE],r[SIZE],edge; VAL sum; void clear(){memset(e,edge=sum=0,sizeof(e));} ARC& REV(PTR x){return arc[(x-arc)^1];} int flow(int S, int T){return spfa_johnson(S,T,INF);} PTR add_edge(int x, int y, int c, VAL w = 0){ e[x]=&(arc[edge++]=(ARC){y,c,+w,e[x]}); e[y]=&(arc[edge++]=(ARC){x,0,-w,e[y]}); return e[x]; } int aug(int S, int T, int& can){ int x,z=T,use=can; for(x=S;x!=T;x=now[x]->t) if(use>now[x]->c) use=now[z=x]->c; for(x=S;x!=T;x=now[x]->t){ now[x]->c-=use; REV(now[x]).c+=use; sum+=use*now[x]->w; } can-=use; return z; } int spfa_johnson(int S, int T, int can){ if(S==T) return can; int in=can,x,m; VAL phi[SIZE],len[SIZE],MAXW=1000000007; memset(l,0,sizeof(l)); fill_n(phi,SIZE,MAXW); phi[r[0]=T]=0; for(int i=m=0;i<=m;i++){ l[x=r[i%SIZE]]=0; for(PTR u=e[x];u;u=u->o){ if(phi[x]+REV(u).w>=phi[u->t] || !REV(u).c) continue; phi[u->t]=phi[x]+REV(u).w; if(!l[u->t]) l[r[++m%SIZE]=u->t]=1; } } do{ typedef pair TPL; priority_queue q; fill_n(len,SIZE,MAXW); memset(l,0,sizeof(l)); q.push(TPL(len[T]=0,T)); while(q.size()){ x=q.top().second; q.pop(); if(!l[x]) l[x]=1; else continue; for(PTR u=e[x];u;u=u->o){ if(!REV(u).c || l[u->t]) continue; VAL at=len[x]+phi[x]+REV(u).w-phi[u->t]; if(at>=len[u->t]) continue; len[u->t]=at; now[u->t]=&REV(u); q.push(TPL(-at,u->t)); } } for(x=0;x