【模板】网络流和匈牙利及二分图染色算法模板
并不全,仅含SAP算法和spfa+增广路,还有hungary。
SAP:(最大流问题)
int sap(int x,int flow)
{
if(x==n) return flow;
int dlt=0,tmp;
for(int it=la[x];it;it=nt[it])
{
if(dis[en[it]]+1==dis[x]&&v[it])
{
tmp = sap(en[it],min(flow-dlt,v[it]));
dlt+=tmp;
v[it]-=tmp;
v[it^1]+=tmp;
if(dis[S]>=n||dlt==flow) return dlt;
}
}
if(dis[S]>=n) return dlt;
cnt[dis[x]]--;
if(!cnt[dis[x]]) dis[S]=n;
dis[x]++;
cnt[dis[x]]++;
return dlt;
}
main()
{
int ans=0;
while(dis[S]<n)
{
ans+=sap(S,inf);
}
}
Hungary:(二分图匹配问题)
int vis[maxn],link[maxn];
bool hungary(int x,int id)
{
int ss=ve[x].size();
for(int i=0;i<ss;i++)
{
int en=ve[x][i];
if(vis[en]==id) continue;
vis[en]=id;
if((!link[en])||(hungary(link[en],id)))
{
link[en]=x;
return true;
}
}
return false;
}
main()
{
int ans=0;
for(int i=1;i<=n;i++) ans+=hungary(i,i);
}
SPFA+增广路(费用流问题)(不要用dijstra,有负边!)
bool rd[maxn]; int dis[maxn],epath[maxn],path[maxn];
int mincost,maxflow;
void addflow()
{
int flow=inf;
for(int i=T;i!=S;i=path[i])
{
flow=min(flow,v[epath[i]]);
}
maxnflow+=flow;
mincost+=flow*dis[T];
for(int i=T;i!=S;i=path[i])
{
v[epath[i]]-=flow;
v[epath[i]^1]+=flow;
}
}
void spfa(int x)
{
for(int i=1;i<=n;i++) {
dis[i]=inf; path[i]=-1; epath[i]=-1; rd[i]=0;
}
dis[x]=path[x]=0; q.push(x); rd[x]=1;
while(q.size())
{
x=q.front(); q.pop(); rd[x]=0;
for(int it=la[x];it;it=nt[it])
{
if(v[it]&&dis[en[it]]>dis[x]+len[it])
{
dis[en[it]]=dis[x]+len[it];
path[en[it]]=x; epath[en[it]]=it;
if(!rd[en[it]])
{
rd[en[it]]=1; q.push(en[it]);
}
}
}
}
if(dis[T]<inf) return true; else return false;
}
二分图染色
bool dfs(int x)
{
for(int i=ve[x].size()-1;i>=0;i--)
{
if(!col[ve[x][i]])
{
col[ve[x][i]] = 3-col[x];
if(!dfs(ve[x][i])) return false;
}
else if(col[ve[x][i]]==col[x]) return false;
}
return true;
}
for(int i=1;i<=2*n;i++)
{
if(!col[i])
{
col[i] = 1;
if(!dfs(i)) { flag=0;break ; }
}
}

浙公网安备 33010602011771号