• [bzoj1412][ZJOI2009]狼和羊的故事


    bzoj100题啦  纪念一下。

    ----------------------------------------------------------------------------------------------------------------------------------------------

    题意:给定一个n*m的图,每一个点可以是狼,用2表示,或者是1-羊,或者是0,表示这里没有动物。你要修尽量少的围墙,使得狼和羊都被隔开。

    题解:很容易想到最小割。我们从S向每一头羊连INF的边,狼向T连INF的边,然后羊或者空点都向四周羊以外的点连边,跑最小割。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define S 0
    #define T 10001
    #define INF 2000000000
    using namespace std;
    inline int read()
    {
        int x = 0 , f = 1; char ch = getchar();
        while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}
        while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
        return x * f;
    }
    
    int d[T+5],c[T+5],head[T+5],n,m,q[T+5],top,cnt=1;
    int st[105][105];
    const int dis[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
    struct edge{int to,next,w;}e[T*100];
    
    void ins(int f,int t,int w)
    {
        e[++cnt]=(edge){t,head[f],w};head[f]=cnt;
        e[++cnt]=(edge){f,head[t],0};head[t]=cnt;
        //cout<<"ins"<<f<<" "<<t<<" "<<w<<endl; 
    }
    
    int dfs(int x,int f)
    {
        if(x==T)return f;
        int used=0;
        for(int&i=c[x];i;i=e[i].next)
            if(e[i].w&&d[e[i].to]==d[x]+1)
            {
                int w=dfs(e[i].to,min(f-used,e[i].w));
                used+=w;e[i].w-=w;e[i^1].w+=w;
                if(used==f)return f;
            }
        return d[x]=0,used;
    }
    
    bool bfs()
    {
        memset(d,0,sizeof(d));int i,j;
        for(d[q[top=i=0]=S]=1;i<=top;i++)
            for(int j=c[q[i]]=head[q[i]];j;j=e[j].next)
                if(e[j].w&&!d[e[j].to])
                    d[q[++top]=e[j].to]=d[q[i]]+1;
        return d[T];
    }
    
    int main()
    {
        n=read();m=read();
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                st[i][j]=read();
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                if(st[i][j]==1) ins(S,(i-1)*m+j,INF);
                if(st[i][j]==2) ins((i-1)*m+j,T,INF);
                if(st[i][j]==2) continue;
                for(int k=0;k<4;k++)
                {
                    int xx=i+dis[k][0],yy=j+dis[k][1];
                    if(xx<1||yy<1||xx>n||yy>m) continue;
                    if(st[xx][yy]!=1)
                        ins((i-1)*m+j,(xx-1)*m+yy,1);    
                }
            }
        int ans=0;
        while(bfs()) ans+=dfs(S,INF);
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    python爬虫headers设置后无效解决方案
    idea建立web项目servlet映射的地址/jsp访问不到
    bootstrap栅格系统错位问题
    python2 python3共存解决方案
    Springboot+Thymeleaf框架的button错误
    星空雅梦
    星空雅梦
    星空雅梦
    星空雅梦
    星空雅梦
  • 原文地址:https://www.cnblogs.com/FallDream/p/bzoj1412.html
Copyright © 2020-2023  润新知