您的位置:首页 > 理论基础 > 计算机网络

1391: [Ceoi2008]order|网络流

2016-01-16 10:09 417 查看
裸的最大权闭合图

注意要用当前弧优化

不然会T的

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<vector>
#define T 3330003
#define ll long long
using namespace std;
int sc()
{
int i=0; char c=getchar();
while(c>'9'||c<'0')c=getchar();
while(c>='0'&&c<='9')i=i*10+c-'0',c=getchar();
return i;
}
int dis[2555],q[2555],cur[2555];
int head[2555],lst[T],nxt[T],v[T];
int tot=1,n,m,S,W;
long long ans;
void insert(int x,int y,int z)
{
lst[++tot]=y; v[tot]=z; nxt[tot]=head[x]; head[x]=tot;
lst[++tot]=x; v[tot]=0; nxt[tot]=head[y]; head[y]=tot;
}
bool BFS()
{
memset(dis,0,sizeof(dis)); dis[S]=1;
int l=1,r=2;q[1]=S;
while(l<r)
{
int x=q[l++];
for(int i=head[x];i;i=nxt[i])
if(v[i]&&!dis[lst[i]])
{
dis[lst[i]]=dis[x]+1;
q[r++]=lst[i];
}
}
return dis[W]!=0;
}
int dfs(int x,int f)
{
if(x==W)return f;
int ww=0,w;
for(int i=cur[x];i;i=nxt[i])
if(v[i]&&dis[lst[i]]==dis[x]+1)
{
w=dfs(lst[i],min(f-ww,v[i]));
ww+=w; v[i]-=w; v[i^1]+=w;
if(v[i]>0)cur[x]=i;
if(f==ww)return f;
}
if(!ww)dis[x]=0;
return ww;
}
int main()
{
n=sc();m=sc();
S=n+m+1;W=S+1;
for(int i=1;i<=n;i++)
{
int x=sc(),t=sc();
insert(S,i,x);
for(int j=1;j<=t;j++)
{
int y=sc(),c=sc();
insert(i,n+y,c);
}
ans+=x;
}
for(int i=1;i<=m;i++)
{
int x=sc();
insert(n+i,W,x);
}
while(BFS())
{
for(int i=1;i<=W;i++)cur[i]=head[i];
ans-=dfs(S,T);
}
cout<<ans;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  网络流