zoukankan      html  css  js  c++  java
  • bzoj2127

    2127: happiness

    Time Limit: 51 Sec  Memory Limit: 259 MB
    Submit: 2492  Solved: 1205
    [Submit][Status][Discuss]

    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的非负整数

     

    转载自http://blog.csdn.net/vmurder/article/details/42609669

     

    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define N 50005
    #define M 300000
    #define P 105
    #define inf 0x3f3f3f3f
    using namespace std;
    struct KSD
    {
        int v,len,next;
    }e[M];
    int head[N],cnt;
    inline void add(int u,int v,int len)
    {
        e[++cnt].v=v;
        e[cnt].len=len;
        e[cnt].next=head[u];
        head[u]=cnt;
        e[++cnt].v=u;
        e[cnt].len=len;
        e[cnt].next=head[v];
        head[v]=cnt;
    }
    int s,t,d[N];
    queue<int>q;
    bool bfs()
    {
        while(!q.empty())q.pop();
        memset(d,0,sizeof(d));
        int i,u,v;
        q.push(s),d[s]=1;
        while(!q.empty())
        {
            u=q.front(),q.pop();
            for(i=head[u];i;i=e[i].next)
            {
                v=e[i].v;
                if(!d[v]&&e[i].len)
                {
                    d[v]=d[u]+1;
                    if(v==t)return 1;
                    q.push(v);
                }
            }
        }
        return 0;
    }
    int dinic(int x,int flow)
    {
        if(x==t)return flow;
        int remain=flow,i,v,k;
        for(i=head[x];i&&remain;i=e[i].next)
        {
            v=e[i].v;
            if(d[v]==d[x]+1&&e[i].len)
            {
                k=dinic(v,min(remain,e[i].len));
                if(!k)d[v]=0;
                e[i].len-=k,e[i^1].len+=k;
                remain-=k;
            }
        }
        return flow-remain;
    }
    int n,m,id[P][P];
    int sum,maxflow;
    void build()
    {
        int i,j,a,temp;
        scanf("%d%d",&n,&m),temp=n*m;
        s=n*m+2*(n-1)*m+2*n*(m-1)+1,t=n*m+2*(n-1)*m+2*n*(m-1)+2;
        for(i=1;i<=n;i++)for(j=1;j<=m;j++)id[i][j]=++cnt;
            cnt=1;
        // 第一个矩阵为n行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学选择文科获得的喜悦值。
        for(i=1;i<=n;i++)for(j=1;j<=m;j++)
        {
            scanf("%d",&a);
            sum+=a;
            add(s,id[i][j],a);
        }
        // 第二个矩阵为n行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学选择理科获得的喜悦值。
        for(i=1;i<=n;i++)for(j=1;j<=m;j++)
        {
            scanf("%d",&a);
            sum+=a;
            add(id[i][j],t,a);
        }
        // 第三个矩阵为n-1行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学与第i+1行第j列的同学同时选择文科获得的额外喜悦值。
        for(i=1;i<n;i++)for(j=1;j<=m;j++)
        {
            scanf("%d",&a);
            sum+=a,++temp;
            add(id[i][j],temp,a),add(id[i+1][j],temp,a);
            add(s,temp,a);
        }
        // 第四个矩阵为n-1行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学与第i+1行第j列的同学同时选择理科获得的额外喜悦值。
        for(i=1;i<n;i++)for(j=1;j<=m;j++)
        {
            scanf("%d",&a);
            sum+=a,++temp;
            add(id[i][j],temp,a),add(id[i+1][j],temp,a);
            add(temp,t,a);
        }
        // 第五个矩阵为n行m-1列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学与第i行第j+1列的同学同时选择文科获得的额外喜悦值。
        for(i=1;i<=n;i++)for(j=1;j<m;j++)
        {
            scanf("%d",&a);
            sum+=a,++temp;
            add(id[i][j],temp,a),add(id[i][j+1],temp,a);
            add(s,temp,a);
        }
        // 第六个矩阵为n行m-1列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学与第i行第j+1列的同学同时选择理科获得的额外喜悦值。
        for(i=1;i<=n;i++)for(j=1;j<m;j++)
        {
            scanf("%d",&a);
            sum+=a,++temp;
            add(id[i][j],temp,a),add(id[i][j+1],temp,a);
            add(temp,t,a);
        }
    }
    int main()
    {
    //    freopen("test.in","r",stdin);
        build();
        while(bfs())maxflow+=dinic(s,inf);
        printf("%d
    ",sum-maxflow);
        return 0;
    }
  • 相关阅读:
    UNIX高级环境编程(2)FIle I/O - 原子操作、共享文件描述符和I/O控制函数
    UNIX高级环境编程(1)File I/O
    排序算法(2) 堆排序 C++实现
    加深一下BlockingQueue的认识
    测试一下StringBuffer和StringBuilder及字面常量拼接三种字符串的效率
    java中的锁
    Http状态码之:301、302重定向
    学点HTTP知识
    java中的字符串相关知识整理
    在Openfire上弄一个简单的推送系统
  • 原文地址:https://www.cnblogs.com/wsy01/p/7932062.html
Copyright © 2011-2022 走看看