能量魔方

Time Limit: 10 Sec  Memory Limit: 64 MB
[Submit][Status][Discuss]

Description

  小C 有一个能量魔方,这个魔方可神奇了,只要按照特定方式,放入不同的 能量水晶,就可以产生巨大的能量。 能量魔方是一个 N*N*N 的立方体,一共用 N3 个空格可以填充能量水晶。 能量水晶有两种: ·一种是正能量水晶(Positive) ·一种是负能量水晶(Negative) 当这个魔方被填满后,就会依据填充的能量水晶间的关系产生巨大能量。对 于相邻两(相邻就是拥有同一个面)的两个格子,如果这两个格子填充的是一正一 负两种水晶,就会产生一单位的能量。而整个魔方的总能量,就是这些产生的能 量的总和。 现在,小 C 已经在魔方中填充了一些水晶,还有一些位置空着。他想知道, 如果剩下的空格可以随意填充,那么在最优情况下,这个魔方可以产生多少能量。

Input

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

Output

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

Sample Input

  2
  P?
  ??
  
  ??
  N?

Sample Output

  9
  explain:
  PN 
  NP 
  
  NP 
  NN 

HINT

  n<=40

Main idea

  给出一个n*n*n的矩阵,其中每一个方块可以涂两种颜色,相邻的两个方块如果涂上的颜色不同,就会产生能量。已知了一些方块的颜色,询问最多可以的最多能量。

Solution

  发现n<=40,大胆猜测是个网络流。思考过后,发现直接求不好连边,那么我们考虑求出最小损耗,然后用(总收益)-(最小损耗)。

  由于相邻的才对答案有贡献,所以我们想到了黑白染色,将所有点划分为两类,那么显然将相邻的点都连一条双向边,权值为1。然后我们考虑如何处理已经规定的点,这时候可以令S集表示1,令T集表示0,将白点的1连向T权值为INF,将S连向黑点的1权值为INF,这样就可以表示不可选了,点权为0则相反。然后跑一遍最小割,计算即可。

Code

 #include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
#define ID(x,y,z) ((z-1)*n*n + (x-1)*n + y) const int ONE=;
const int TWO=;
const int INF=; int n,S,T;
char ch[ONE],c;
int a[][][];
int next[TWO],first[TWO],go[TWO],w[TWO],tot;
int q[],tou,wei;
int Dep[ONE],E[TWO];
int Ans; int get()
{
int res=,Q=;char c;
while( (c=getchar())< || c> )
if(c=='-')Q=-;
res=c-;
while( (c=getchar())>= && c<= )
res=res*+c-;
return res*Q;
} void Add(int u,int v,int z)
{
next[++tot]=first[u]; first[u]=tot; go[tot]=v; w[tot]=z;
next[++tot]=first[v]; first[v]=tot; go[tot]=u; w[tot]=;
} void Double_Add(int u,int v,int z)
{
Add(u,v,z);
Add(v,u,z);
} int PD(int x,int y,int z)
{
return (x+y+z)%;
} int Bfs()
{
memset(Dep,,sizeof(Dep));
tou=; wei=; Dep[]=; q[]=;
for(int u=;u<=T-;u++) E[u]=first[u];
while(tou<wei)
{
int u=q[++tou];
for(int e=first[u];e;e=next[e])
{
int v=go[e];
if(Dep[v] || !w[e]) continue;
Dep[v]=Dep[u]+;
q[++wei]=v;
}
}
return Dep[T]>;
} int Dfs(int u,int Limit)
{
if(u==T || !Limit) return Limit;
int flow=,f;
for(int &e=E[u];e;e=next[e])
{
int v=go[e];
if(Dep[v]!=Dep[u]+ || !w[e]) continue;
f=Dfs(v,min(Limit,w[e]));
w[e]-=f;
w[((e-)^)+]+=f;
Limit-=f;
flow+=f;
if(!Limit) break;
}
return flow;
} int main()
{
cin>>n; S=; T=n*n*n+;
for(int z=;z<=n;z++)
for(int x=;x<=n;x++)
{
scanf("%s",ch+);
for(int y=;y<=n;y++)
{
if(ch[y]=='?') a[x][y][z]=;
if(ch[y]=='P') a[x][y][z]=;
if(ch[y]=='N') a[x][y][z]=;
}
} for(int z=;z<=n;z++)
for(int x=;x<=n;x++)
for(int y=;y<=n;y++)
{
if(a[x+][y][z]) Double_Add(ID(x,y,z),ID(x+,y,z),),Ans++;
if(a[x][y+][z]) Double_Add(ID(x,y,z),ID(x,y+,z),),Ans++;
if(a[x][y][z+]) Double_Add(ID(x,y,z),ID(x,y,z+),),Ans++; if(a[x][y][z]==)
{
if(PD(x,y,z)) Add(S,ID(x,y,z),INF);
else Add(ID(x,y,z),T,INF);
} if(a[x][y][z]==)
{
if(PD(x,y,z)) Add(ID(x,y,z),T,INF);
else Add(S,ID(x,y,z),INF);
}
} while(Bfs())
{
Ans-=Dfs(S,INF);
} printf("%d",Ans);
}

【BZOJ1976】能量魔方 [最小割]的更多相关文章

  1. 【二分 最小割】cf808F. Card Game

    Digital collectible card games have become very popular recently. So Vova decided to try one of thes ...

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

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

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

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

  4. 【bzoj1976】[BeiJing2010组队]能量魔方 Cube 网络流最小割

    题目描述 一个n*n*n的立方体,每个位置为0或1.有些位置已经确定,还有一些需要待填入.问最后可以得到的 相邻且填入的数不同的点对 的数目最大. 输入 第一行包含一个数N,表示魔方的大小. 接下来 ...

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

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

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

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

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

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

  8. 二分图&网络流&最小割等问题的总结

    二分图基础: 最大匹配:匈牙利算法 最小点覆盖=最大匹配 最小边覆盖=总节点数-最大匹配 最大独立集=点数-最大匹配 网络流: 技巧: 1.拆点为边,即一个点有限制,可将其转化为边 BZOJ1066, ...

  9. 基于模糊聚类和最小割的层次化网格分割算法(Hierarchical Mesh Decomposition)

    网格分割算法是三维几何处理算法中的重要算法,具有许多实际应用.[Katz et al. 2003]提出了一种新型的层次化网格分割算法,该算法能够将几何模型沿着凹形区域分割成不同的几何部分,并且可以避免 ...

随机推荐

  1. web框架与爬虫

    所有的web框架 http://www.cnblogs.com/wupeiqi/articles/5341480.html 爬虫技术 http://www.cnblogs.com/wupeiqi/ar ...

  2. Anytime项目开发记录3

    应用想要做的好,反馈必然少不了~哈哈~ 用户的反馈.意见.建议,甚至是谩骂,都是对项目的反馈. 如果一个应用没有听取用户的反馈,那么应用会离着用户越来越远.懂得用户要什么是一回事,听得到用户的反馈,则 ...

  3. 通过调用API在JavaWeb项目中实现证件识别

    本文详细介绍自己如何在JavaWeb项目中通过调用API实现证件识别. 一,Face++使用简介 二,两种方式(图片URL与本地上传)实现证件识别 一,Face++使用简介 Face++旷视人工智能开 ...

  4. 第四篇 Python循环

    While 循环 For 循环

  5. Ajax跨域请求解决方式

    前端 jQuery方式 .ajax({ type: "POST", url: "http://xxx.com/api/test", dataType: 'jso ...

  6. C语言关于“输入包含多行数据,请处理到文件结束”的问题

    今天,笔者在做本校ACM校赛网络赛的时候,遇到输入格式中有这样的要求:输入包含多行数据,请处理到文件结束.题目的逻辑很简单,主要功能代码很容易实现,但是题目中没有“明确”指出控制台中输入数据以什么方式 ...

  7. [PocketFlow]解决在coco上mAP非常低的bug

    1.问题 继上次训练挂起的bug后,又遇到了现在评估时AP非常低的bug.具体有多低呢?Pelee论文中提到,用128的batchsize大小在coco数据集上训练70K次迭代后,AP@0.5:0.9 ...

  8. Jquery append()总结(一) 转载

    转载自:http://dushanggaolou.iteye.com/blog/1173457 append(content)  /** * 向每个匹配的元素内部追加内容. * 这个操作与对指定的元素 ...

  9. HBase 高可用性

    1.Replication 之 Master <--> Master 互备 Master1 (所用zookeeper所处节点 hadoop[01-05] ): -- add_peer '1 ...

  10. io学习-相关文章

    文章:IO编程 地址:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/00143 ...