zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    求连续子数组的最大和
    【LeetCode练习题】Gas Station
    再来看看快速排序
    【LeetCode练习题】First Missing Positive
    【LeetCode练习题】Merge Sorted Array
    Hdu 2089-不要62 数位dp
    Tsinsen A1517. 动态树 树链剖分,线段树,子树操作
    Bzoj 3505: [Cqoi2014]数三角形 数论
    Poj 3695-Rectangles 矩形切割
    Tsinsen A1505. 树(张闻涛) 倍增LCA,可持久化线段树,DFS序
  • 原文地址:https://www.cnblogs.com/20020723YJX/p/9415477.html
Copyright © 2011-2022 走看看