zoukankan      html  css  js  c++  java
  • 【BZOJ4554】游戏(TJOI&HEOI2016)-二分图匹配/最大流

    测试地址:游戏
    做法:本题需要用到二分图匹配或最大流。
    注意到一个炸弹能炸到的区域是一行中由硬石头分割成的一段以及一列中由硬石头分割成的一段,那么问题等价于,在同一段中只能有一个炸弹,问最多能放多少炸弹。
    我们把一行或一列中由硬石头分割成的连续一段看做点,那么实际上一个可放炸弹的位置就代表一条边,连接它所在的行段和列段,问题就变成,最多能取多少条边,使得每个点至多属于一条边的端点,这显然就是一个二分图最大匹配,用匈牙利算法或最大流解决即可。
    以下是本人代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int inf=1000000000;
    int n,m,S,T,r[55][55],c[55][55],totid=0;
    int first[5010]={0},tot=1,lvl[5010],cur[5010],h,t,q[5010];
    char s[55][55];
    struct edge
    {
        int v,next,f;
    }e[20010];
    
    void insert(int a,int b,int f)
    {
        e[++tot].v=b,e[tot].next=first[a],e[tot].f=f,first[a]=tot;
        e[++tot].v=a,e[tot].next=first[b],e[tot].f=0,first[b]=tot;
    }
    
    void init()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%s",s[i]+1);
            for(int j=1;j<=m;j++)
            {
                if (j==1||s[i][j-1]=='#') totid++;
                r[i][j]=totid;
            }
        }
        for(int j=1;j<=m;j++)
            for(int i=1;i<=n;i++)
            {
                if (i==1||s[i-1][j]=='#') totid++;
                c[i][j]=totid;
            }
        S=totid+1,T=totid+2;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                if (j==1||s[i][j-1]=='#') insert(S,r[i][j],1);
                if (i==1||s[i-1][j]=='#') insert(c[i][j],T,1);
                if (s[i][j]=='*') insert(r[i][j],c[i][j],1);
            }
    }
    
    bool makelevel()
    {
        for(int i=1;i<=T;i++)
            lvl[i]=-1,cur[i]=first[i];
        h=t=1;
        q[1]=S;
        lvl[S]=0;
        while(h<=t)
        {
            int v=q[h++];
            for(int i=first[v];i;i=e[i].next)
                if (e[i].f&&lvl[e[i].v]==-1)
                {
                    lvl[e[i].v]=lvl[v]+1;
                    q[++t]=e[i].v;
                }
        }
        return lvl[T]!=-1;
    }
    
    int maxflow(int v,int maxf)
    {
        int ret=0,f;
        if (v==T) return maxf;
        for(int i=cur[v];i;i=e[i].next)
        {
            if (e[i].f&&lvl[e[i].v]==lvl[v]+1)
            {
                f=maxflow(e[i].v,min(maxf-ret,e[i].f));
                ret+=f;
                e[i].f-=f;
                e[i^1].f+=f;
                if (ret==maxf) break;
            }
            cur[v]=i;
        }
        if (!ret) lvl[v]=-1;
        return ret;
    }
    
    void dinic()
    {
        int maxf=0;
        while(makelevel())
            maxf+=maxflow(S,inf);
        printf("%d",maxf);
    }
    
    int main()
    {
        init();
        dinic();
    
        return 0;
    }
  • 相关阅读:
    解决:Could not resolve archetype org.apache.maven.archetypes
    Spring MVC配置MyBatis输出SQL
    Spring集成MyBatis 通用Mapper以及 pagehelper分页插件
    关于SpringMVC或Struts2接受参数接收不到的原因
    配置quartz启动时就执行一次
    ajaxFileUpload进行文件上传时,总是进入error
    spring mvc注入配置文件里的属性
    java中将一个文件夹下所有的文件压缩成一个文件
    flume failed to start agent because dependencies were not found in classpath
    ubuntu不能安装pip unable to install pip in unbuntu
  • 原文地址:https://www.cnblogs.com/Maxwei-wzj/p/9793435.html
Copyright © 2011-2022 走看看