zoukankan      html  css  js  c++  java
  • P3973 [TJOI2015]线性代数 最小割

    题意:

    戳这里

    分析:

    [D=sum_{j=1}^nA_{1,j} imes (sum_{i=1}^nA_{1,i}B_{i,j}-C_{1,j}) ]

    我们观察式子可以发现 (B_{i,j}) 会被选当且仅当 (A_{1,i},A_{1,j}) 都为 1,(-C_{1,j}) 会被选当且仅当 (A_{1,j}) 为 1

    也就是说 (B_{i,j})(-C_{1,i},-C_{1,j}) 必须同时存在,也就是说选了 (B_{i,j}) 就得减少 (C_{1,i}+C_{1,j}) 这个东西好像很最小割,我们只要把 (B_{i,j}) 到汇点路径上的流量表示为 (C_{1,i}+C_{1,j}) 那么要么不选 (B_{i,j}) 要么必须减少 (C_{1,i}+C_{1,j})

    具体做法就是:

    1. 对于每一个 (B_{i,j},C_{1,i}) 建立一个点
    2. 源点向所有的 (B_{i,j}) 连一条流量为 (B_{i,j}) 的边,(C_{1,i}) 向汇点连一条流量为 (C_{1,i}) 的边
    3. 每一个 (B_{i,j})(C_{1,i},C_{1,j}) 连一条流量为 (inf) 的边
    4. 求最小割,答案等于 (sum B_{i,j}-mincut)

    代码:

    #include<bits/stdc++.h>
    #define inl inline
    #define reg register
    #define id(i,j) (i-1)*n+j
    using namespace std;
    
    namespace zzc
    {
        typedef long long ll;
        inl ll read()
        {
            ll x=0,f=1;char ch=getchar();
            while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
            while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
            return x*f;
        }
    
        const ll maxn = 3e5+5;
        const ll inf = 0x3f3f3f3f3f3f3f3f;
        ll n,cnt=1,st,ed,ans;
        ll head[maxn],dep[maxn],cur[maxn];
        queue<ll> q;
        struct edge
        {
            ll to,nxt,w;
        }e[maxn<<3];
    
        inl void add(ll u,ll v,ll w)
        {
            e[++cnt].to=v;
            e[cnt].w=w;
            e[cnt].nxt=head[u];
            head[u]=cnt;
        }
    
        inl void add_edge(ll u,ll v,ll w)
        {
            add(u,v,w);add(v,u,0);
        }
    
        inl bool bfs()
        {
            for(reg ll i=st;i<=ed;i++) dep[i]=-1;
            dep[st]=0;q.push(st);
            while(!q.empty())
            {
                ll u=q.front();q.pop();
                for(reg ll i=head[u];i;i=e[i].nxt)
                {
                    ll v=e[i].to;
                    if(e[i].w&&dep[v]==-1)
                    {
                        dep[v]=dep[u]+1;
                        q.push(v);
                    }
                }
            }
            return dep[ed]!=-1;
        }
    
        ll dfs(ll u,ll flow)
        {
            if(u==ed) return flow;
            ll w,used=0;
            for(reg ll &i=cur[u];i;i=e[i].nxt)
            {
                ll v=e[i].to;
                if(e[i].w&&dep[v]==dep[u]+1)
                {
                    w=dfs(v,min(flow-used,e[i].w));
                    e[i].w-=w;
                    e[i^1].w+=w;
                    used+=w;
                    if(used==flow) return used;
                }
            }
            if(!used) dep[u]=-1;
            return used;
        }
    
        inl void dinic()
        {
            while(bfs())
            {
                memcpy(cur,head,sizeof(head));
                ans-=dfs(st,inf);
            }
        }
    
        void work()
        {
            ll a;
            n=read();st=0;ed=n*n+n+1;
            for(reg ll i=1;i<=n;i++) for(reg ll j=1;j<=n;j++) a=read(),ans+=a,add_edge(st,id(i,j),a),add_edge(id(i,j),id(n+1,i),inf),add_edge(id(i,j),id(n+1,j),inf);
            for(reg ll i=1;i<=n;i++) a=read(),add_edge(id(n+1,i),ed,a);
            dinic();
            printf("%lld
    ",ans);
        }
    
    }
    
    int main()
    {
        zzc::work();
        return 0;
    }
    
    
  • 相关阅读:
    Candy leetcode java
    Trapping Rain Water leetcode java
    Best Time to Buy and Sell Stock III leetcode java
    Best Time to Buy and Sell Stock II leetcode java
    Best Time to Buy and Sell Stock leetcode java
    Maximum Subarray leetcode java
    Word Break II leetcode java
    Word Break leetcode java
    Anagrams leetcode java
    Clone Graph leetcode java(DFS and BFS 基础)
  • 原文地址:https://www.cnblogs.com/youth518/p/14387577.html
Copyright © 2011-2022 走看看