zoukankan      html  css  js  c++  java
  • 1001: [BeiJing2006]狼抓兔子

    /**************************************************************
        Problem: 1001
        User: whymhe
        Language: C++
        Result: Accepted
        Time:1236 ms
        Memory:106760 kb
    ****************************************************************/
     
    //Pro:P4001 [BJOI2006]狼抓兔子
     
    //大概就是求个最小割
    //这个题的唯一的难点大概就是如何给网格图编号 
     
    //一个比较坑的地方:
    //边都是双向的,所以正反向弧的容量都是flow 
     
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
     
    inline int read()
    {
        char c=getchar();int num=0;
        for(;!isdigit(c);c=getchar());
        for(;isdigit(c);c=getchar())
            num=num*10+c-'0';
        return num; 
    }
     
    const int N=1e6+5;
     
    int n,m,S,T;
    int head[N],num_edge;
    struct Edge
    {
        int v,flow,nxt;
    }edge[N<<3];
     
    inline void add_edge(int u,int v,int flow)
    {
        edge[++num_edge].v=v;
        edge[num_edge].flow=flow;
        edge[num_edge].nxt=head[u];
        head[u]=num_edge;
    }
     
    int from[N],dep[N];
    inline bool bfs()
    {
        queue<int> que;
        int now;
        for(now=S;now<=T;++now)
            dep[now]=0,from[now]=head[now];
        que.push(S),dep[S]=1;
        while(!que.empty())
        {
            now=que.front(),que.pop();
            for(int i=head[now],v;i;i=edge[i].nxt)
            {
                v=edge[i].v;
                if(dep[v]||!edge[i].flow)
                    continue;
                dep[v]=dep[now]+1;
                if(v==T)
                    return 1;
                que.push(v);
            }
        }
        return 0;
    }
     
    int dfs(int u,int flow)
    {
        if(u==T||!flow)
            return flow;
        int outflow=0,tmp;
        for(int &i=from[u],v;i;i=edge[i].nxt)
        {
            v=edge[i].v;
            if(dep[v]!=dep[u]+1)
                continue;
            tmp=dfs(v,min(flow,edge[i].flow));
            if(!tmp)
                continue;
            flow-=tmp;
            outflow+=tmp;
            edge[i].flow-=tmp;
            edge[i^1].flow+=tmp;
            if(!flow)
                return outflow;
        }
        dep[u]=0;
        return outflow;
    }
     
    int main()
    {
        num_edge=1;
        n=read(),m=read();
        S=1,T=n*m;
        for(int i=1,p,f;i<=n;++i)
        {
            for(int j=1;j<m;++j)
            {
                p=(i-1)*m+j;
                f=read();
                add_edge(p,p+1,f);
                add_edge(p+1,p,f);
            }
        }
        for(int i=1,p,f;i<n;++i)
        {
            for(int j=1;j<=m;++j)
            {
                p=(i-1)*m+j;
                f=read(),
                add_edge(p,p+m,f);
                add_edge(p+m,p,f);
            }
        }
        for(int i=1,p,f;i<n;++i)
        {
            for(int j=1;j<m;++j)
            {
                p=(i-1)*m+j;
                f=read();
                add_edge(p,p+m+1,f);
                add_edge(p+m+1,p,f);
            }
        }
        long long ans=0;
        while(bfs())
            ans+=1ll*dfs(S,0x7fffffff);
        printf("%lld",ans);
        return 0;
    }
  • 相关阅读:
    Java使用Preconditions.checkNotNull(.....)判空对象, 并处理可能的NullPointerException异常
    jdk1.8
    BigDecimal
    BIOS的启动原理学习--加载引导程序
    Linux系统想要切换到root用户时出现authentication failure
    Ubuntu Linux 操作系统与实验教程--Linux系统的基本组成
    Java中“==”和equals()的区别
    自己编写操作系统2--初始镜像编写以及VM启动
    关于Windows下子系统WSL的思考
    自己编写操作系统1--概述
  • 原文地址:https://www.cnblogs.com/lovewhy/p/9633649.html
Copyright © 2011-2022 走看看