zoukankan      html  css  js  c++  java
  • [TYVJ1338] QQ农场

    描述

    这个农场和游戏中略有不同。土地实际上是一个边长为N的正方形,由N*N块土地组成。
    在每块土地上,都种有一种农作物。如果他选择摘取一块土地上的农作物,就能获得一个固定的利润(当然,这个利润是正数)。不同土地上的利润多半是不同的。
    贪心的Sandytea本想摘取所有土地上的农作物。但是正当他准备行动时,却被告知不允许摘取了两块有公共边的土地上的作物,否则就会被主人的狗发现。
    Sandytea想知道,在不被狗抓住的前提下,他能获得的最大利益是多少。

    输入格式

    第一行:一个整数N,表示土地是一个边长为N的正方形。
    下面N行:每行N个正整数,描述了各块土地上的农作物的单位价值。

    输出格式

    输出一行,包含一个整数,为最大的收益。

    测试样例1

    输入


    7 7 
    54 54

    输出

    61

    备注

    数据范围:
    有10分的数据满足:N≤6
    另有20分的数据满足:N≤13
    另有30分的数据满足:N≤50
    另有40分的数据满足:N≤200
    所有数据满足:每块土地上作物的价值不超过100。
     
    最小割:最大化利益=最小化损失
    把网格黑白染色,
    由源点向黑格连容量为格点权值的边,白格向汇点连容量为格点权值的边,每个黑格子向相邻的格子连容量为inf的边
    把黑格子割到源点表示采摘该格作物,否则不采摘
    把白格子割到汇点表示采摘该格作物,否则不采摘
    为什么相邻格子要连INF的边呢?
    题目说,不能采相邻格子的作物,而如果连INF的边,就说明这条边必不可能被割断,相邻格子就必不可能都能被采摘(否则S到T连通)
    注意,必须从黑格(即为与源点连边的格子)向白格(即为与汇点连边的格子)连边
    不能从白格向黑格连边或黑白格互相连边(即从黑格向白格连边,白格也向黑格连边)
    为什么呢?
    如果互相连边,那么下图1,3两个点就变相有了限制关系,而事实上并不是取了1号点就不能取3号点(1号点只与2号点相邻)
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int INF=1999999999;
    int h[1000000],next[1000000],cap[1000000],to[1000000],k=1;
    int level[40100],que[40100],head,tail,iter[40100],n;
    int x[4]={-1,0,1,0},y[4]={0,-1,0,1}; 
    void ins(int u,int v,int c){next[++k]=h[u];h[u]=k;to[k]=v;cap[k]=c;}
    int get(int i,int j){return (i-1)*n+j;}
    bool bfs(int S,int T)
    {
        memset(level,0,sizeof(level));
        head=tail=0;que[tail++]=S;level[S]=1;
        while(head<tail)
        {
            int u=que[head++];
            for(int i=h[u];i;i=next[i])
            {
                int v=to[i];
                if(!level[v]&&cap[i])
                {
                    level[v]=level[u]+1;que[tail++]=v;
                }
            }
        }
        if(!level[T])return 0;return 1;
    }
    int dfs(int u,int T,int f)
    {
        if(u==T)return f;
        int used=0;
        for(int &i=iter[u];i;i=next[i])
        {
            int v=to[i];
            if(level[v]==level[u]+1&&cap[i])
            {
                int w=dfs(v,T,min(cap[i],f-used));used+=w;
                if(w)
                {
                    cap[i]-=w;cap[i^1]+=w;if(f==used)return f;
                }
            }
        }
        return used;
    }
    int dinic(int S,int T)
    {
        int flow=0;
        while(1)
        {
            for(int i=0;i<=n*n+1;i++)iter[i]=h[i];
            if(!bfs(S,T))return flow;flow+=dfs(S,T,INF);
        }
    }
    int main()
    {
        scanf("%d",&n);int S=0,T=n*n+1,tot=0;
        for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        {
            int v;scanf("%d",&v);tot+=v;
            if(i%2==j%2){ins(get(i,j),T,v);ins(T,get(i,j),0);}
            else 
            {
                for(int k=0;k<4;k++)
                {
                    int ii=i+x[k],jj=j+y[k];if(ii<1||ii>n||jj<1||jj>n)continue;
                    ins(get(i,j),get(ii,jj),INF);ins(get(ii,jj),get(i,j),0);
                }
                ins(S,get(i,j),v);ins(get(i,j),S,0);
            }
        }
        cout<<tot-dinic(S,T);
        return 0;
     } 
  • 相关阅读:
    安装django时出错
    mysql ------python3(一)笔记
    安装mysql的具体过程
    Python3web框架---Django、Tornado、Flask的对比
    python3-----json函数
    图片人脸识别年龄和性别
    urllib库的使用(三)-----python3 异常处理
    python 3 基础篇 (一)
    requests,pymysql,django的安装
    求素数方法的改进
  • 原文地址:https://www.cnblogs.com/lher/p/7581417.html
Copyright © 2011-2022 走看看