P4313 文理分科 网络流

 其实也就卡了卡常,,,

先考虑没有same_art和same_science 。

起点用art的流量连向每个点,该点再用science的流量连向终点,断开哪边相当于少了哪边收益。

先全部收益加起来,再减去最小割即可。

那有same这些情况怎么办呢。

考虑新建节点v,起点以same_art连向v,断开即代表不获得这段收益。如何避免这个点不断开s的同时它覆盖区的点断开了s?再用v点向覆盖区连权值为inf的边,即可保证覆盖区的点要断则该点必断。same_science同理,在下不加以赘述。

528ms,勉强能卡过,,

#include<bits/stdc++.h>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<deque>
#include<list>
#include<set>
#include<vector>
#include<iostream>
#define ll int
#define re register
#define inf 0x7f7f7ff
#define inl inline
#define sqr(x) (x*x)
//#define eps 1e-8
#define debug printf("debug
");
//#pragma comment(linker, "/STACK:1024000000,1024000000")
//#pragma GCC optimize (2)
//#pragma G++ optimize (2)
using namespace std;
const ll mod=51123987;
const ll MAXN=105;
inl ll read() {
    re ll x = 0; re int f = 1;
    char ch = getchar();
    while(ch<'0'||ch>'9') { if(ch== '-' ) f = -1; ch = getchar(); }
    while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x * f;
}
inl char readc() {
    char ch=getchar();
    while(('z'<ch||ch<'a')&&('Z'<ch||ch<'A')) ch=getchar();
    return ch;
}
inl void write(re ll x){
    if(x>=10)write(x/10);
    putchar(x%10+'0');
}
inl void writeln(re ll x){
    if(x<0) {x=-x;putchar('-');}
    write(x); puts("");
}
inl ll gcd(re ll x,re ll y){while(y^=x^=y^=x%=y);return x;}
inl ll Lcm(re ll a,re ll b) {return a/gcd(a,b)*b;}
inl void FR() {
    freopen(".in","r",stdin);
    freopen(".out","w",stdout);
}
inl void FC() {
    fclose(stdin);
    fclose(stdout);
}
struct edge{
    ll u,v,w,nxt;
}e[400005<<1];
ll ans,n,m,cnt=1,head[200005<<1],s,t,sst;
ll dx[10]={0,0,0,1,-1};
ll dy[10]={0,1,-1,0,0};
inl void adde(ll u,ll v,ll w) {
    e[++cnt].u=u;e[cnt].v=v;
    e[cnt].w=w;e[cnt].nxt=head[u];
    head[u]=cnt;
}
ll d[200005<<1],cur[200005<<1];
inl bool bfs() {
    queue<ll>Q;
    for(re ll i=s;i<=sst;i++) d[i]=0;
    Q.push(s);d[s]=1;
    while(!Q.empty()) {
        re ll x=Q.front();Q.pop();
        for(re ll h=head[x];h;h=e[h].nxt) {
            re ll v=e[h].v;
            if(e[h].w&&!d[v]) {
                d[v]=d[x]+1;
                if(v==t) return true ;
                Q.push(v);
            }
        }
    }
    return d[t];
}
ll dfs(ll x,ll limit) {
    if(x==t) return limit;
    ll used=0;
    for(re ll h=cur[x];h;h=e[h].nxt) {
        if(used==limit) break;
        if(d[e[h].v]==d[x]+1&&e[h].w) {
            ll t=dfs(e[h].v,min(limit-used,e[h].w));
            used+=t;e[h].w-=t;e[h^1].w+=t;
        }
    }
    if(!used) d[x]=0;
    return used;
}
int main() {
//  FR();
    n=read(),m=read();s=0;t=n*m+1;sst=t;
    for(re ll i=1;i<=n;i++) {
        for(re ll j=1;j<=m;j++) {
            re ll x=read();
            adde(s,(i-1)*m+j,x);
            adde((i-1)*m+j,s,0);
            ans+=x;
        }
    }
    for(re ll i=1;i<=n;i++) {
        for(re ll j=1;j<=m;j++)  {
            re ll x=read();
            adde((i-1)*m+j,t,x);
            adde(t,(i-1)*m+j,0);
            ans+=x;
        }
    }
    for(re ll i=1;i<=n;i++) {
        for(re ll j=1;j<=m;j++) {
            re ll x=read();
            ans+=x;sst++;
            adde(s,sst,x);adde(sst,s,0);
            for(re ll k=0;k<=4;k++) {
                re ll xx=i+dx[k],yy=j+dy[k];
                if(xx&&xx<=n&&yy&&yy<=m) {
                    adde(sst,(xx-1)*m+yy,inf);
                    adde((xx-1)*m+yy,sst,0);
                }
            }
        }
    }
    for(re ll i=1;i<=n;i++) {
        for(re ll j=1;j<=m;j++) {
            re ll x=read();
            ans+=x;sst++;
            adde(sst,t,x);adde(t,sst,0);
            for(re ll k=0;k<=4;k++) {
                re ll xx=i+dx[k],yy=j+dy[k];
                if(xx&&xx<=n&&yy&&yy<=m) {
                    adde((xx-1)*m+yy,sst,inf);
                    adde(sst,(xx-1)*m+yy,0);
                }
            }
        }
    }
    while(bfs()) {
        memcpy(cur,head,sizeof(cur));
        ans-=dfs(s,inf);
    }
    writeln(ans);
//  FC();
    return 0;
}
原文地址:https://www.cnblogs.com/20020723YJX/p/9415477.html