题目描述

一个n*n*n的立方体,每个位置为0或1。有些位置已经确定,还有一些需要待填入。问最后可以得到的 相邻且填入的数不同的点对 的数目最大。

输入

第一行包含一个数N,表示魔方的大小。 接下来 N2 行,每行N个字符,每个字符有三种可能: P:表示此方格已经填充了正能量水晶; N:表示此方格已经填充了负能量水晶; ?:表示此方格待填充。 上述 N*N 行,第(i-1)*N+1~i*N 行描述了立方体第 i 层从前到后,从左到右的 状态。且每 N 行间,都有一空行分隔。

输出

仅包含一行一个数,表示魔方最多能产生的能量

样例输入

2
P?
??

??
N?

样例输出

9


题解

网络流最小割

经典的最小割建模了,这里讲一下做法吧:

由于要求数目最大,因此将其转化为 总可能数目-不满足条件的数目 ,于是就是要最小化不满足条件的数目。

考虑什么样的不满足条件:选择相同。因此当选择相同时应产生1的代价,最小化这个代价,即最小割问题。

对立方体黑白染色,然后:

对于白点:如果确定了为0则S向其连容量为inf的边,如果确定了为1则其向T连容量为inf的边;

对于黑点:反转源汇,即0连T,1连S。

对于相邻的两个点,在它们之间连容量为1的双向边。

跑最小割即为最小的不满足条件的数目。

讲道理这种经典建模现在看来还是蛮简单的。

#include <queue>
#include <cstdio>
#include <cstring>
#define N 125010
#define M 1500010
#define inf 1 << 30
#define pos(i , j , k) (i - 1) * n * n + (j - 1) * n + k
using namespace std;
queue<int> q;
int head[N] , to[M] , val[M] , next[M] , cnt = 1 , s , t , dis[N];
char str[60];
inline void add(int x , int y , int z)
{
to[++cnt] = y , val[cnt] = z , next[cnt] = head[x] , head[x] = cnt;
to[++cnt] = x , val[cnt] = z , next[cnt] = head[y] , head[y] = cnt;
}
bool bfs()
{
int x , i;
memset(dis , 0 , sizeof(dis));
while(!q.empty()) q.pop();
dis[s] = 1 , q.push(s);
while(!q.empty())
{
x = q.front() , q.pop();
for(i = head[x] ; i ; i = next[i])
{
if(val[i] && !dis[to[i]])
{
dis[to[i]] = dis[x] + 1;
if(to[i] == t) return 1;
q.push(to[i]);
}
}
}
return 0;
}
int dinic(int x , int low)
{
if(x == t) return low;
int temp = low , i , k;
for(i = head[x] ; i ; i = next[i])
{
if(val[i] && dis[to[i]] == dis[x] + 1)
{
k = dinic(to[i] , min(temp , val[i]));
if(!k) dis[to[i]] = 0;
val[i] -= k , val[i ^ 1] += k;
if(!(temp -= k)) break;
}
}
return low - temp;
}
int main()
{
int n , i , j , k , ans = 0;
scanf("%d" , &n) , s = 0 , t = n * n * n + 1;
for(i = 1 ; i <= n ; i ++ )
{
for(j = 1 ; j <= n ; j ++ )
{
scanf("%s" , str + 1);
for(k = 1 ; k <= n ; k ++ )
{
if((i + j + k) & 1)
{
if(str[k] == 'P') add(s , pos(i , j , k) , inf);
if(str[k] == 'N') add(pos(i , j , k) , t , inf);
}
else
{
if(str[k] == 'P') add(pos(i , j , k) , t , inf);
if(str[k] == 'N') add(s , pos(i , j , k) , inf);
if(i > 1) add(pos(i , j , k) , pos(i - 1 , j , k) , 1) , ans ++ ;
if(i < n) add(pos(i , j , k) , pos(i + 1 , j , k) , 1) , ans ++ ;
if(j > 1) add(pos(i , j , k) , pos(i , j - 1 , k) , 1) , ans ++ ;
if(j < n) add(pos(i , j , k) , pos(i , j + 1 , k) , 1) , ans ++ ;
if(k > 1) add(pos(i , j , k) , pos(i , j , k - 1) , 1) , ans ++ ;
if(k < n) add(pos(i , j , k) , pos(i , j , k + 1) , 1) , ans ++ ;
}
}
}
}
while(bfs()) ans -= dinic(s , inf);
printf("%d\n" , ans);
return 0;
}

【bzoj1976】[BeiJing2010组队]能量魔方 Cube 网络流最小割的更多相关文章

  1. BZOJ1976: [BeiJing2010组队]能量魔方 Cube

    1976: [BeiJing2010组队]能量魔方 Cube Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 832  Solved: 281[Submi ...

  2. 【BZOJ1976】[BeiJing2010组队]能量魔方 Cube 最小割

    [BZOJ1976][BeiJing2010组队]能量魔方 Cube Description 小C 有一个能量魔方,这个魔方可神奇了,只要按照特定方式,放入不同的 能量水晶,就可以产生巨大的能量. 能 ...

  3. Bzoj 1976: [BeiJing2010组队]能量魔方 Cube 最小割,最大流

    1976: [BeiJing2010组队]能量魔方 Cube Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 879  Solved: 304[Submi ...

  4. BZOJ 1976 能量魔方 Cube(最小割)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1976 题意:给出一个n*n*n的立方体.每个小单位为字母P或者字母N.相邻两个小单位字母 ...

  5. 【BZOJ-1976】能量魔方Cube 最小割 + 黑白染色

    1976: [BeiJing2010组队]能量魔方 Cube Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 884  Solved: 307[Submi ...

  6. 【题解】 bzoj3894: 文理分科 (网络流/最小割)

    bzoj3894,懒得复制题面,戳我戳我 Solution: 首先这是一个网络流,应该还比较好想,主要就是考虑建图了. 我们来分析下题面,因为一个人要么选文科要么选理科,相当于两条流里面割掉一条(怎么 ...

  7. 【bzoj3774】最优选择 网络流最小割

    题目描述 小N手上有一个N*M的方格图,控制某一个点要付出Aij的代价,然后某个点如果被控制了,或者他周围的所有点(上下左右)都被控制了,那么他就算是被选择了的.一个点如果被选择了,那么可以得到Bij ...

  8. 【bzoj1143】[CTSC2008]祭祀river Floyd+网络流最小割

    题目描述 在遥远的东方,有一个神秘的民族,自称Y族.他们世代居住在水面上,奉龙王为神.每逢重大庆典, Y族都会在水面上举办盛大的祭祀活动.我们可以把Y族居住地水系看成一个由岔口和河道组成的网络.每条河 ...

  9. 【bzoj1797】[Ahoi2009]Mincut 最小割 网络流最小割+Tarjan

    题目描述 给定一张图,对于每一条边询问:(1)是否存在割断该边的s-t最小割 (2)是否所有s-t最小割都割断该边 输入 第一行有4个正整数,依次为N,M,s和t.第2行到第(M+1)行每行3个正 整 ...

随机推荐

  1. mybatis的坑——不报错,就是不能committing,数据存不进数据库

    测试的时候会报空指针异常,在项目跑的时候会停止执行程序,不会出现异常. 经过一星期的排查与测试,最终找到错误,把mapper文件的映射属性名写错了. property属性名要与接收类的属性名保持一致. ...

  2. 精读《12 个评估 JS 库你需要关心的事》

    1 引言 作者给出了从 12 个角度全面分析 JS 库的可用性,分别是: 特性. 稳定性. 性能. 包生态. 社区. 学习曲线. 文档. 工具. 发展历史. 团队. 兼容性. 趋势. 下面总结一下作者 ...

  3. 在唯一密钥属性“fileExtension”设置为“.”时,无法添加类型为“mimeMap”的重复集合项

    在ASP.NET 网站的配置文件中添加了MIME类型,但是运行网站后在IIS上和页面上提示"在唯一密钥属性“fileExtension”设置为“.woff”时,无法添加类型为“mimeMap ...

  4. Python中的文件和目录操作实现

    Python中的文件和目录操作实现 对于文件和目录的处理,虽然可以通过操作系统命令来完成,但是Python语言为了便于开发人员以编程的方式处理相关工作,提供了许多处理文件和目录的内置函数.重要的是,这 ...

  5. IDEA工具配置weblogic

    1.首先打开IDEA,点击Run-Edit Configurations… 2.配置weblogic页面 2.1点击“+”号,选WeblogicServer-local 2.2红框的是新添加的服务,起 ...

  6. java 二进制、位运算、和移位运算符(2013-07-30-bd 写的日志迁移

    二进制是逢2进位的进位制,0.1是基本算符, 1字节=8位 比如 int a =1 ;int 占4个字节在计算机里表示为: java中的4个位运算,分别是“按位与&.按位或|.按位异或^,按位 ...

  7. U盘装机记录

    U盘装机记录 1. 将U盘制作为启动盘(安装PE文件到U盘). (1)准备材料 8G以上U盘一个 一个可信的启动盘制作工具(这里是用的老毛桃) (2)将U盘插入电脑,单击老毛桃客户端(出现如下图所示的 ...

  8. ubuntu安装wine 和sourceinsght

    ubuntu安装wine: 1.sudo apt-get update 2.sudo apt-get install wine 安装完成后会在当前用户目录的的家目录下生成.wine目录,该目录就是wi ...

  9. [USACO1.5] 回文质数

    P1217  Prime Palindromes 题目描述 因为151既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 151 是回文质数. 写一个程序来找出范围[a,b](5 < ...

  10. POJ:2236-Wireless Network

    Wireless Network Time Limit: 10000MS Memory Limit: 65536K Total Submissions: 34265 Accepted: 14222 D ...