【JZOJ 4201】【BZOJ 4177】Mike的农场

来源:互联网 发布:linux修改主机名不重启 编辑:程序博客网 时间:2024/05/16 05:40

description

这里写图片描述

Solution

很明显的最小割,
每一个点,向S连一条流量ai的边,向T连bi的边,
对于每个相互影响,把i,j连一条双向流量k的边,
额外的收入则新建一个点,如a=0,向S连一条b的边,并向集合S的每个点连流量无限边,a=1则反之,

Code

我加了当前弧优化还慢了?!
这里写图片描述

#include<cstdio>#include<cstdlib> #define fo(i,a,b) for(int i=a;i<=b;i++)#define efo(i,q) for(int i=A[q];i;i=B[i][0])using namespace std;typedef long long LL;const int N=5500,maxlongint=1047483640;int read(int &n){    char ch=' ';int q=0,w=1;    for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar());    if(ch=='-')w=-1,ch=getchar();    for(;ch>='0' && ch<='9';ch=getchar())q=q*10+ch-48;n=q*w;return n;}int n,m,m1,S,T;LL ans;int A[N*2],A1[N*2],B[100*N][3],B0=1;int h[N*2],hv[N*2];int min(int a,int b){return a>b?b:a;}void link(int q,int w,int e,int e1){    if(!A[q])A1[q]=B0+1;    B[++B0][0]=A[q],A[q]=B0,B[B0][1]=w,B[B0][2]=e;    if(!A[w])A1[w]=B0+1;    B[++B0][0]=A[w],A[w]=B0,B[B0][1]=q,B[B0][2]=e1;}LL aug(int q,LL e){    if(q==T)return e;    LL mi=T+2;LL E=e;    int i1=A1[q];    efo(i,q)    {        if(B[i][2])        {            int w=B[i][1];            if(h[q]==h[w]+1)            {                LL t=aug(w,min(e,B[i][2]));                B[i][2]-=t;                B[i^1][2]+=t;                e-=t;                if(h[S]>T+1||!e)                {                    B[A1[q]][0]=A[q];                    A[q]=i;A1[q]=i1;B[A1[q]][0]=0;                    return E-e;                }            }            mi=min(mi,h[w]);        }        i1=i;    }    if(E==e)    {        if((--hv[h[q]])==0)h[S]=T+2;        hv[h[q]=mi+1]++;    }    return E-e;}int main(){    freopen("work.in","r",stdin);    freopen("work.out","w",stdout);    int q,w,e;    read(n),read(m1),read(m);    S=0,T=n+m+1;ans=0;    fo(i,1,n)read(q),link(S,i,q,0),ans+=q;    fo(i,1,n)read(q),link(i,T,q,0),ans+=q;    fo(i,1,m1)read(q),read(w),read(e),link(q,w,e,e);    fo(i,1,m)    {        read(q),read(w),read(e);        if(!q)continue;        ans+=e;        if(!w)link(S,n+i,e,0);else link(n+i,T,e,0);        fo(j,1,q)        {            read(e);            if(w)link(e,n+i,maxlongint,0);else link(n+i,e,maxlongint,0);        }    }    hv[0]=T+1;    while(h[S]<T+1)ans-=aug(S,maxlongint);    printf("%d\n",ans);    return 0;}
0 0
原创粉丝点击