码迷,mamicode.com
首页 > 其他好文 > 详细

luoguP1361 小M的作物 最小割

时间:2020-03-19 21:21:21      阅读:48      评论:0      收藏:0      [点我收藏+]

标签:main   col   memset   name   oid   return   ++   net   eof   

非常经典的最小割模型. 

code:   

#include <bits/stdc++.h>    
#define N 3006       
#define ll long long 
#define setIO(s) freopen(s".in","r",stdin)  
using namespace std; 
const ll inf=2000000001;    
namespace net
{
    struct Edge
    {
        int u,v;
        ll c;
        Edge(int u=0,int v=0,ll c=0):u(u),v(v),c(c){}
    };  
    queue<int>q;
    vector<Edge>edges; 
    vector<int>G[N];
    int vv[N],vis[N],d[N],s,t;      
    void add(int u,int v,ll c)
    {
        edges.push_back(Edge(u,v,c));
        edges.push_back(Edge(v,u,0)); 
        int o=edges.size(); 
        G[u].push_back(o-2);
        G[v].push_back(o-1);     
    }   
    ll dfs(int x,ll cur)
    {
        if(x==t)
            return cur; 
        ll an=0,flow=0;
        for(int i=vv[x];i<G[x].size();++i,++vv[x])      
        {
            Edge e=edges[G[x][i]]; 
            if(e.c>0&&d[e.v]==d[x]+1)
            {    
                an=dfs(e.v,min(cur,e.c));  
                if(an)
                {
                    cur-=an;
                    flow+=an;           
                    edges[G[x][i]].c-=an;
                    edges[G[x][i]^1].c+=an;   
                    if(!cur)
                        break;  
                }
            }
        }
        return flow;
    }
    int bfs() 
    {   
        memset(vis,0,sizeof(vis));
        d[s]=0;
        vis[s]=1;
        q.push(s);
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            for(int i=0;i<G[u].size();++i)
            {
                if(edges[G[u][i]].c>0)
                {
                    int v=edges[G[u][i]].v; 
                    if(!vis[v])
                    {
                        vis[v]=1;
                        d[v]=d[u]+1; 
                        q.push(v); 
                    }
                }
            }
        }
        return vis[t];
    }  
    ll maxflow()
    {
        ll re=0;
        while(bfs())  
        {
            memset(vv,0,sizeof(vv));          
            re+=(ll)dfs(s,inf); 
        }
        return re;
    }
};   
ll a[N],b[N];     
int main() 
{   
    // setIO("input");  
    int n;    
    scanf("%d",&n);      
    for(int i=1;i<=n;++i)   
        scanf("%lld",&a[i]);      
    for(int i=1;i<=n;++i)   
        scanf("%lld",&b[i]);     
    int s=0,t=n+1,m,tot=n+2;       
    scanf("%d",&m);    
    ll Sum=0;    
    for(int i=1;i<=m;++i) 
    {
        int k; 
        ll c1,c2;  
        scanf("%d%lld%lld",&k,&c1,&c2);     
        Sum+=c1+c2;   
        int n1=++tot,n2=++tot;    
        net::add(s,n1,c1);   
        net::add(n2,t,c2);    
        for(int j=1;j<=k;++j) 
        {
            int x;   
            scanf("%d",&x);    
            net::add(n1,x,inf);   
            net::add(x,n2,inf);   
        }
    }          
    for(int i=1;i<=n;++i)   
    {
        net::add(s,i,a[i]);   
        net::add(i,t,b[i]);   
        Sum+=a[i]+b[i];   
    } 
    net::s=s,net::t=t;  
    printf("%lld\n",Sum-net::maxflow());   
    return 0; 
}

  

luoguP1361 小M的作物 最小割

标签:main   col   memset   name   oid   return   ++   net   eof   

原文地址:https://www.cnblogs.com/guangheli/p/12527069.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!