CODEVS 1907 方格取数 3

来源:互联网 发布:cnc串联程序软件 编辑:程序博客网 时间:2024/05/16 02:38

调代码の血的教训

(吐血.jpg)
此处不止我一个人吐血。我还叫了一个大神帮我调代码,此处不只我一个人吐血。

最大流 = 最小割 = 最小点权覆盖集 = sum-最大点权独立集
详细看这里

  • 题目大意

    «问题描述:
    在一个有m*n 个方格的棋盘中,每个方格中有一个正整数。现要从方格中取数,使任
    意2 个数所在方格没有公共边,且取出的数的总和最大。试设计一个满足要求的取数算法。
    «编程任务:
    对于给定的方格棋盘,按照取数要求编程找出总和最大的数。

  • 输入描述

    第1 行有2 个正整数m和n,分别表示棋盘的行数
    和列数。接下来的m行,每行有n个正整数,表示棋盘方格中的数。

  • 输出描述 Output Description

    将取数的最大总和输出

  • 样例输入 Sample Input
    3 3
    1 2 3
    3 2 3
    2 3 1

  • 样例输出 Sample Output

    11

  • 数据范围及提示 Data Size & Hint

    n,m<=30

分析

首先,如果知道的话,就很容易想到这个:
最大流 = 最小割 = 最小点权覆盖集 = sum-最大点权独立集
因为与每个格子相邻的格子只有上下左右4个,所以建图的时候相邻的格子连权值为inf的边,以保证跑最小割的时候不割此边。
因为原图不是二分图的形式,所以我们通过染色的方法将其转化为二分图的形式。相邻的格子颜色互异,就像国际象棋的棋盘。。
然后所有一种颜色的格子向S连边,另一种颜色的格子向T连边,权值为格子的值。
再跑一遍最大流就好了。

再说说自己调代码的经历。
我直接复制自己以前写的模板,然后,就悲剧了。记录层数的数组是定义在模板里的,定义的是d[N].然而,我定义N的时候,写的是 N = 40 (格子边长为30)。呵。
然后就死调。
。。。
所以像这样,以矩阵的每一个点做状态的时候,可以一开始就定义 N = 边长×边长。

代码

#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>#include <queue>using namespace std;const int N = 50, inf = 0x3f3f3f3f;int map[N*N], line[N*N*10][3], lt;int col[N][N], book[N][N], e[N][N];int n, m, S, T, sum;int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};int get(int x, int y) {    return ((x-1)*m + y);}void ins(int a, int b, int w){    line[lt][1] = b;    line[lt][2] = w;    line[lt][0] = map[a];    map[a] = lt++;}int d[N*N];bool bfs() {    queue <int> q;    memset(d, 0xff, sizeof(d));    q.push(S);    d[S] = 0;    while(!q.empty()) {        int u = q.front();        q.pop();        for(int i = map[u]; i != -1; i = line[i][0]) {            int v = line[i][1];            if(d[v] == -1 and line[i][2]) {                d[v] = d[u] + 1;                q.push(v);            }        }     }    return d[T] != -1;}int dfs(int u, int f) {    if(u == T) return f;    int ans = 0;    for(int i = map[u]; i != -1 and f - ans; i = line[i][0]) {        int v = line[i][1];        if(d[v] == d[u] + 1 and line[i][2]) {            int del = dfs(v, min(f-ans, line[i][2]));            line[i][2] -= del;            line[i^1][2] += del;            if((ans+=del) == f) return ans;        }    }    if(ans == 0) d[u] = -1;    return ans;}int Dinic() {    int res = 0;    while(bfs()) {        res += dfs(S, inf);    }    return res;}int main() {    memset(map, 0xff, sizeof(map));    scanf("%d%d", &n, &m);    S = 0, T = n*m + 1;    for(int i = 1; i <= n; i++) {        for(int j = 1; j <= m; j++) {            if(j == 1) col[i][j] = col[i-1][j]^1;            else col[i][j] = col[i][j-1]^1;            int w;            scanf("%d", &w);            e[i][j] = w;            sum += w;            book[i][j] = get(i,j);            if(col[i][j]) {                ins(S, get(i,j), w), ins(get(i,j), S, 0);                for(int k = 0; k < 4; k++) {                    int x = i + dir[k][0], y = j + dir[k][1];                    if(x > 0 && x <= n && y > 0 && y <= m) {                        ins(get(i,j), get(x,y), inf), ins(get(x,y), get(i,j), 0);                    }                }            }            else                ins(get(i,j), T, w), ins(T, get(i,j), 0);        }    }    printf("%d\n", sum - Dinic());    return 0;}
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 京东商品超过售后期怎么办 京东过了售后期怎么办 京东售后不处理怎么办 京东售后不让退货怎么办 天猫盒子遥控器丢了怎么办 淘宝店铺的客服不理人怎么办 淘宝假货下架了怎么办 淘宝不让发布本地生活服务了怎么办 淘宝删除差评后店家不返现怎么办 天猫店家迟迟不发货怎么办 淘宝下单后店家说缺货怎么办 用淘宝把话费冲到空号上怎么办 d速快递没有网点怎么办 京东买的货没收到怎么办 淘宝物流显示已揽件就是不动怎么办 淘宝查不到物流信息怎么办 快递物流信息更新错怎么办 淘宝上查不到物流怎么办 微信买的东西不给退怎么办 微信购物已收货怎么办 微信买东西不退怎么办 银行经营贷款资金回流怎么办 淘宝有运费险换货怎么办 淘宝有运费险的换货怎么办 淘宝换货一直不发货怎么办 淘宝申请换货卖家不发货怎么办 淘宝买家泄露卖家信息怎么办 高仿苹果没内存怎么办 高仿苹果7太卡怎么办 天猫客服处理不了怎么办 美团顾客电话打不通怎么办 美团众包顾客电话打不通怎么办 天猫退货商家拒绝退款怎么办 中关村买电脑被骗了怎么办 在闲鱼被买家骗了东西怎么办 在手机店买手机被骗怎么办 买手机分期付款被骗了怎么办 买电脑被骗了怎么办啊 小米卡puk锁了怎么办 红米3x电池松动怎么办 实体店买到苹果翻新机怎么办