1391: [Ceoi2008]order|网络流

来源:互联网 发布:如何在ubuntu下编程c 编辑:程序博客网 时间:2024/06/05 16:58

裸的最大权闭合图

注意要用当前弧优化

不然会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 longusing 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;}


0 0