您的位置:首页 > 其它

BZOJ2502: 清理雪道

2016-04-06 19:53 369 查看
有下界的最小流

注意推流操作

切边然后重连边

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: