有下界的最小流
注意推流操作
切边然后重连边
#include<cstdio>
#include<cmath>
#include<queue>
#include<iostream>
#include<cstring>
using namespace std;
struct Chain
{
int u,flow;
Chain *next,*Pair;
}*Head[10001];
inline void Add(int u,int v,int flow)
{
Chain *tp=new Chain;
tp->next=Head[u];tp->u=v;tp->flow=flow;Head[u]=tp;
tp=new Chain;
tp->next=Head[v];tp->u=u;tp->flow=0;Head[v]=tp;
Head[u]->Pair=Head[v];Head[v]->Pair=Head[u];
}
int S,T;
const
int INF=1<<29;
int H[1000001];
queue<int>Q;
inline bool BFS()
{
memset(H,-1,sizeof(H));
H[S]=1;
Q.push(S);
while(!Q.empty())
{
int u=Q.front();
Q.pop();
for(Chain *tp=Head[u];tp;tp=tp->next)
if(H[tp->u]==-1&&tp->flow)
H[tp->u]=H[u]+1,Q.push(tp->u);
}
return H[T]!=-1;
}
int DFS(int u,int flow)
{
int res=flow,t;
if(u==T)return flow;
for(Chain *tp=Head[u];tp;tp=tp->next)
if(H[tp->u]==H[u]+1&&tp->flow)
{
t=DFS(tp->u,min(res,tp->flow)) ;
res-=t;
tp->flow-=t;
tp->Pair->flow+=t;
if(!res)return flow;
}
if(res)H[u]=-1;
return flow-res;
}
inline int Dinic()
{
int res=0,t;
while(BFS())res+=t=DFS(S,INF);
return res;
}
int In[101];
char c;
inline void read(int &a)
{
a=0;do c=getchar();while(c<'0'||c>'9');
while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}
bool R[1001];
int main()
{
int n,i,s,e,j,k,l,t;
read(n);
S=n+1;
T=n+2;
s=n+3,e=n+4;
for(i=1;i<=n;i++)
{
read(t);
In[i]+=t;
while(t--)
{
read(j);
In[j]--;
Add(i,j,INF);
}
}
Add(e,s,INF);
for(i=1;i<=n;Add(s,i++,INF),Add(i-1,e,INF))
if(In[i]<0)
Add(S,i,-In[i]);
else Add(i,T,In[i]);
// Add(S,s,INF);
// Add(e,T,INF);
Dinic();
long long f1=0;
for(Chain *tp=Head[S];tp;tp=tp->next)
tp->flow=tp->Pair->flow=0;
for(Chain *tp=Head[T];tp;tp=tp->next)
tp->flow=tp->Pair->flow=0;
for(Chain *tp=Head[e];tp;tp=tp->next)
if(tp->u==s)
f1+=tp->Pair->flow,tp->flow=tp->Pair->flow=0;
Add(S,e,INF);
Add(s,T,INF);
long long f2=Dinic();
printf("%lld\n",f1-f2);
return 0;
}
本文介绍了一种求解有下界最小流问题的算法实现,通过使用Dinic算法进行求解,并展示了如何通过建立图模型来处理此类问题。文章详细解释了增广路径搜索、流量调整等关键步骤。
1365

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



