zoukankan      html  css  js  c++  java
  • bzoj 2127: happiness

    2127: happiness

    http://www.lydsy.com/JudgeOnline/problem.php?id=2127

    Time Limit: 51 Sec  Memory Limit: 259 MB

    Description

    高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友。这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友如果能同时选文科或者理科,那么他们又将收获一些喜悦值。作为计算机竞赛教练的scp大老板,想知道如何分配可以使得全班的喜悦值总和最大。

    Input

    第一行两个正整数n,m。接下来是六个矩阵第一个矩阵为n行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学选择文科获得的喜悦值。第二个矩阵为n行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学选择理科获得的喜悦值。第三个矩阵为n-1行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学与第i+1行第j列的同学同时选择文科获得的额外喜悦值。第四个矩阵为n-1行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学与第i+1行第j列的同学同时选择理科获得的额外喜悦值。第五个矩阵为n行m-1列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学与第i行第j+1列的同学同时选择文科获得的额外喜悦值。第六个矩阵为n行m-1列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学与第i行第j+1列的同学同时选择理科获得的额外喜悦值。

    Output

    输出一个整数,表示喜悦值总和的最大值

    Sample Input

    1 2
    1 1
    100 110
    1
    1000

    Sample Output

    1210
    【样例说明】
    两人都选理,则获得100+110+1000的喜悦值。
    【数据规模】
    对于100%以内的数据,n,m<=100 所有喜悦值均为小于等于5000的非负整数
     
    最大收益转化为最小损失
    因为如果以收益跑最大流,每条增广路流量实际上是增广路上的最小流量
    所以不是最大收益
    对下图跑最小割
    ans=所有权值和-最小割
     
     
     
    #include<cstdio>
    #include<queue>
    #include<algorithm>
    #define N 50101
    #define M N*30
    #define inf 2e9
    using namespace std;
    int front[N],to[M],nxt[M],tot=1;
    int lev[N],cap[M],cur[N];
    int n,m,src,decc,ans,cnt;
    queue<int>q;
    int turn(int i,int j) { return (i-1)*m+j; }
    void add(int u,int v,int w)
    {
        to[++tot]=v; nxt[tot]=front[u]; front[u]=tot; cap[tot]=w;
        to[++tot]=u; nxt[tot]=front[v]; front[v]=tot;
    }
    bool bfs()
    {
        while(!q.empty()) q.pop();
        for(int i=0;i<=cnt;i++) cur[i]=front[i],lev[i]=-1;
        lev[src]=0; q.push(src);
        int now;
        while(!q.empty())
        {
            now=q.front(); q.pop();
            for(int i=front[now];i;i=nxt[i])
            {
                if(cap[i]>0&&lev[to[i]]==-1)
                {
                    lev[to[i]]=lev[now]+1;
                    if(to[i]==decc) return true;
                    q.push(to[i]);
                }
            }
        }
        return false;
    }
    int dinic(int now,int flow)
    {
        if(now==decc) return flow;
        int rest=0,delta;
        for(int &i=cur[now];i;i=nxt[i])
        {
            if(cap[i]>0&&lev[to[i]]>lev[now])
            {
                delta=dinic(to[i],min(flow-rest,cap[i]));
                if(delta) 
                {
                    cap[i]-=delta; cap[i^1]+=delta;
                    rest+=delta; if(rest==flow) break; 
                }
            }
        }
        if(rest!=flow) lev[now]=-1;
        return rest;
    }
    int main()
    {
        int x;
        scanf("%d%d",&n,&m);
        decc=n*m+1;
        for(int i=1;i<=n;i++)
         for(int j=1;j<=m;j++)
          {
              scanf("%d",&x); ans+=x;
              add(src,turn(i,j),x);
          }
        for(int i=1;i<=n;i++)
         for(int j=1;j<=m;j++)
          {
              scanf("%d",&x); ans+=x;
              add(turn(i,j),decc,x);
          }
        cnt=n*m+1;
        for(int i=1;i<n;i++)
         for(int j=1;j<=m;j++)
          {
              scanf("%d",&x); ans+=x;
              cnt++;
              add(src,cnt,x);
              add(cnt,turn(i,j),inf);
              add(cnt,turn(i+1,j),inf);
          }
        for(int i=1;i<n;i++)
         for(int j=1;j<=m;j++)
          {
              scanf("%d",&x); ans+=x;
              cnt++;
              add(cnt,decc,x);
              add(turn(i,j),cnt,inf);
              add(turn(i+1,j),cnt,inf);
              add(cnt-(n-1)*m,cnt,inf);
          }
        for(int i=1;i<=n;i++)
         for(int j=1;j<m;j++)
         {
             scanf("%d",&x); ans+=x;
             cnt++;
             add(src,cnt,x);
             add(cnt,turn(i,j),inf);
             add(cnt,turn(i,j+1),inf);
         }
        for(int i=1;i<=n;i++)
         for(int j=1;j<m;j++)
         {
             scanf("%d",&x); ans+=x;
             cnt++;
             add(cnt,decc,x);
             add(turn(i,j),cnt,inf);
             add(turn(i,j+1),cnt,inf);
             add(cnt-n*(m-1),cnt,inf);
         }
        while(bfs()) ans-=dinic(src,inf);
        printf("%d",ans);
    }
  • 相关阅读:
    Atitit 经济学常见的流派 古典主义与凯恩斯主义
    Atitit 学习方法 体系化学习方法 Excel 科目,分类,专业 三级分类。。 知识点。。 课程就是每一个知识点的详细化。。 比如经济学 类别 专业 xx概论知识点 3、金
    atiitt it学科体系化 体系树与知识点概念大总结.xlsx
    Atitit 减少财政支出普通人如何蹭政府补贴措施 attilax大总结.docx
    Atitit 信用管理概论 attilax学习心得
    Atitit.月度计划日程表 每月流程表v5
    Atitit 企业6大职能 attilax总结
    Atitit 常见每日流程日程日常工作.docx v8 ver ampm imp 签到 am y 天气情况检查 am y 晨会,每天或者隔天 am 每日计划(项目计划,日计划等。 am
    Atitit 财政赤字解决方案
    Atitit 建设自己的财政体系 attilax总结 1.1. 收入理论 2 1.2. 收入分类 2 1.3. 2 1.4. 非货币收入 2 1.5. 2 1.6. 降低期望 2 1.7.
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/6882755.html
Copyright © 2011-2022 走看看