正题
板子
有源汇上下界最大流可以通过跑完有源汇上下界可行流后,跑一遍从源到汇的最大流求解.
有源汇上下界可行流可以通过加一条从汇到源的无穷容量边,转化成无源汇上下界可行流来求解.
无源汇上下界可行流可以通过强行先假设下界已经流满,建立超级源汇,若一个点入度>出度,那么就从超级源向该店连一条容量为入度-出度的边,若一个点出度>入度,那么就从该点向超级汇连一条容量为出度-入度的边,判断是否有满足S割集只有超级源来求解.
注意最后跑最大流的时候,要么把可行流的流量记下来(也就是那条汇源边的流量)再加上删去该边的最大流,要么就直接跑最大流输出,啥都不用加,因为肯定会把汇源那条边的流量反向增广,数值也恰好等于可行流的流量.
而超级源超级汇可以不用理,因为增广路不可能经过超级源汇,这个显然.
#include<bits/stdc++.h>
using namespace std;
const int N=2010,M=200010;
struct edge{
int y,nex,c;
}s[M<<1];
int first[N],head[N],len=1,op[N],d[N],qs[N],st,ed;
int n,m,s1,t1,s2,t2;
void ins(int x,int y,int c){s[++len]=(edge){y,first[x],c};first[x]=len;}
bool bfs(int S,int T){
for(int i=1;i<=n+m+4;i++) first[i]=head[i],d[i]=0;
d[qs[st=ed=1]=S]=1;
while(st<=ed){
int x=qs[st++];
for(int i=first[x];i;i=s[i].nex) if(s[i].c && !d[s[i].y]){
d[s[i].y]=d[x]+1;
qs[++ed]=s[i].y;
}
}
return d[T]!=0;
}
int dfs(int x,int T,int t){
if(x==T) return t;
int tot=0;
for(int&i=first[x];i!=0;i=s[i].nex) if(d[s[i].y]==d[x]+1 && s[i].c){
int now=dfs(s[i].y,T,min(t-tot,s[i].c));
s[i].c-=now;s[i^1].c+=now;tot+=now;
if(tot==t) break;
}
return tot;
}
long long Dinic(int S,int T){
long long tot=0;
int dx=0;
while(bfs(S,T)){
dx=dfs(S,T,2e9);
while(dx) tot+=dx,dx=dfs(S,T,2e9);
}
return tot;
}
int main(){
while(~scanf("%d %d",&n,&m)){
s1=n+m+1;t1=n+m+2;s2=n+m+3;t2=n+m+4;
for(int i=1;i<=n+m+4;i++) first[i]=head[i]=op[i]=0;len=1;
int x,ans;
long long tot=0;
int C,D,T,L,R;
for(int i=1;i<=m;i++){
scanf("%d",&x),op[n+i]-=x;op[t1]+=x;
ins(n+i,t1,2e9),ins(t1,n+i,0);
}
for(int i=1;i<=n;i++){
scanf("%d %d",&C,&D);
ins(s1,i,D),ins(i,s1,0);
while(C--){
scanf("%d %d %d",&T,&L,&R);T++;
op[i]-=L;op[n+T]+=L;
ins(i,n+T,R-L);ins(n+T,i,0);
}
}
ins(t1,s1,2e9);ins(s1,t1,0);ans=len;
for(int i=1;i<=n+m+2;i++)
if(op[i]>0) ins(s2,i,op[i]),ins(i,s2,0),tot+=op[i];
else if(op[i]<0) ins(i,t2,-op[i]),ins(t2,i,0);
for(int i=1;i<=n+m+4;i++) head[i]=first[i];
if(Dinic(s2,t2)!=tot) printf("-1\n\n");
else tot=s[ans].c,s[ans].c=s[ans^1].c=0,printf("%lld\n\n",tot+Dinic(s1,t1));
}
}
本文详细介绍了如何通过构建特殊的网络流图解决有源汇上下界的最大流问题,包括将问题转化为无源汇上下界可行流的步骤,并提供了具体的实现代码。
117

被折叠的 条评论
为什么被折叠?



