Codeforces 316C2 棋盘模型
Let’s move from initial matrix to the bipartite graph. The matrix elements (i, j) for which i + j are even should be place to one part, the matrix elements (i, j) for which i + j are uneven should be place to another part. The edges are corresponding to squares which are situated side by side. After that let’s weigh the edges. The edges which connect equal elements of matrix have weights 0, for unequal elements – weight 1. After that the problem is reduced to finding of the maximum independent edge set with minimal weight. Substantiation of above-stated is following: an answer to the problem represents a partitioning of initial matrix for pairs. Note that for any partitioning minimal number of changing matrix elements corresponds to the number of pairs on unequal elements. So in the optimal partitioning the number of pairs of equal elements is maximum. For solving minimum-cost flow problem is needed to use some effective algorithm. For example, Dijkstra algorithm with heap adding conversion of edges weights from Johnson's algorithm.
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 1e5+11;
const int oo = 0x3f3f3f3f;
int to[maxn<<1],cost[maxn<<1],cap[maxn<<1],flow[maxn<<1],nxt[maxn<<1];
int head[maxn],tot;
void init(){
memset(head,-1,sizeof head);
tot=0;
}
void add(int u,int v,int c,int w){
to[tot]=v;
cap[tot]=c;
flow[tot]=0;
cost[tot]=w;
nxt[tot]=head[u];
head[u]=tot++;
swap(u,v);
to[tot]=v;
cap[tot]=0;
flow[tot]=0;
cost[tot]=-w;
nxt[tot]=head[u];
head[u]=tot++;
}
struct QUEUE{
int que[maxn];
int front,rear;
void init(){front=rear=0;}
void push(int x){que[rear++]=x;}
int pop(){return que[front++];}
bool empty(){return front==rear;}
}que;
int n,m,s,t;
bool vis[maxn];
int pre[maxn],dis[maxn];
bool spfa(){
que.init();
memset(vis,0,sizeof vis);
memset(pre,-1,sizeof pre);
memset(dis,oo,sizeof dis);
que.push(s);vis[s]=1;dis[s]=0;
while(!que.empty()){
int u=que.pop(); vis[u]=0;
for(int i = head[u]; ~i; i = nxt[i]){
int v=to[i],c=cap[i],f=flow[i],w=cost[i];
if(c>f&&dis[v]>dis[u]+w){
dis[v]=dis[u]+w;
pre[v]=i;
if(!vis[v]){
que.push(v);
vis[v]=1;
}
}
}
}
if(dis[t]==oo) return 0;
else return 1;
}
int mcmf(){
int mc=0,mf=0;
while(spfa()){
int tf=oo+1;
for(int i = pre[t]; ~i; i = pre[to[i^1]]){
tf=min(tf,cap[i]-flow[i]);
}
mf+=tf;
for(int i = pre[t]; ~i; i = pre[to[i^1]]){
flow[i]+=tf;
flow[i^1]-=tf;
}
mc+=dis[t]*tf;
}
return mc;
}
#define rep(i,j,k) for(int i = j; i <= k; i++)
#define repp(i,j,k) for(int i = j; i < k; i++)
#define repe(i,u) for(int i = head[u]; ~i; i = nxt[i])
#define scan(a) scanf("%d",&a)
#define scann(a,b) scanf("%d%d",&a,&b)
#define scannn(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define println(a) printf("%d\n",a)
#define printbk(a) printf("%d ",a)
#define print(a) printf("%d",a)
int G[100][100],R,C,n1;
inline int ID(int i,int j){
return (i-1)*C+j;
}
inline int chai(int x){
return R*C+x;
}
inline bool black(int i,int j){
return i+j &1;
}
int dx[]={0,1,0,-1};
int dy[]={1,0,-1,0};
int main(){
while(scann(R,C)!=EOF){
init();
rep(i,1,R) rep(j,1,C) scan(G[i][j]);
s=R*C+1;t=s+1;n=t;
rep(i,1,R){
rep(j,1,C){
if(!black(i,j))continue;
rep(d,0,3){
int xx=i+dx[d],yy=j+dy[d];
if(xx<1||xx>R||yy<1||yy>C)continue;
if(G[xx][yy]==G[i][j]){
add(ID(i,j),ID(xx,yy),1,0);
}
else{
add(ID(i,j),ID(xx,yy),1,1);
}
}
}
}
rep(i,1,R) rep(j,1,C){
if(black(i,j)) add(s,ID(i,j),1,0);
else add(ID(i,j),t,1,0);
}
println(mcmf());
}
return 0;
}
Codeforces 316C2 棋盘模型的更多相关文章
- D. Three Pieces(dp,array用法,棋盘模型)
https://codeforces.com/contest/1065/problem/D 题意 给你一个方阵,里面的数字从1~nn,你需要从标号为1的格子依次走到标号为nn,在每一个格子你有两个决策 ...
- Nanami's Digital Board CodeForces - 434B (棋盘dp)
大意: 给定01矩阵, m个操作, 操作1翻转一个点, 操作2求边界包含给定点的最大全1子矩阵 暴力枚举矩形高度, 双指针统计答案 #include <iostream> #include ...
- Codeforces - tag::flows 大合集 [完坑 x14]
589F 题意:给出n个时间区间,每个区间挑定长的非连续区间,求不同个区间不存在时间冲突的最大定长,输出乘上n 二分图模型+二分长度,左顶点集为区间编号,右顶点集为时间编号(1...10000),汇点 ...
- Codeforces 最大流 费用流
这套题目做完后,一定要反复的看! 代码经常出现的几个问题: 本机测试超时: 1.init函数忘记写. 2.addedge函数写成add函数. 3.边连错了. 代码TLE: 1.前向星边数组开小. 2. ...
- 「2017 山东一轮集训 Day4」棋盘(费用流)
棋盘模型 + 动态加边 #include<cstdio> #include<algorithm> #include<iostream> #include<cs ...
- 关于三目运算符与if语句的效率与洛谷P2704题解
题目描述 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用“H” 表示),也可能是平原(用“P”表示),如下图.在每一格平原地形上最 ...
- [SCOI2005]互不侵犯King
题目描述 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. ——by洛谷 https://www. ...
- [入门向选讲] 插头DP:从零概念到入门 (例题:HDU1693 COGS1283 BZOJ2310 BZOJ2331)
转载请注明原文地址:http://www.cnblogs.com/LadyLex/p/7326874.html 最近搞了一下插头DP的基础知识……这真的是一种很锻炼人的题型…… 每一道题的状态都不一样 ...
- JAVA课程设计+五子棋(团队博客)
JAVA课程设计 利用所学习的JAVA知识设计一个五子棋小游戏 1.团队名称.团队成员介绍(菜鸟三人组) 杨泽斌[组长]:201521123049 网络1512 叶文柠[组员]:20152112305 ...
随机推荐
- redis的特性
- 201671010127 2016—2017—2 Java学习周结
时间真是个最公平东西,只要能够好好地利用它,它可以为我们带来我们我们所想要的东西.学习Java已经有一周了,对于Java基础知识的认识也更进一步,对Java的兴趣也愈来愈浓.实现一个Java程序,主要 ...
- Call requires API level 7 (current min is 1):(问题解决)
在一个导入的项目里修改加入webView的时候设置缩放属性的设置报错: Call requires API level 7 (current min is 1): android.webkit.Web ...
- css自动换行 word-break:break-all和word-wrap:break-word(转)
css自动换行 word-break:break-all和word-wrap:break-word 2012-12-31 17:30 by greenal, 159 阅读, 0 评论, 收藏, 编辑 ...
- DOM 操作属性
DOM操作就是针对对象的操作 先写一个按钮,<input tupe="button" value="" id="id"> 这 ...
- 项目一:第十四天 1.在realm中动态授权 2.Shiro整合ehcache 缓存realm中授权信息 3.动态展示菜单数据 4.Quartz定时任务调度框架—Spring整合javamail发送邮件 5.基于poi实现分区导出
1 Shiro整合ehCache缓存授权信息 当需要进行权限校验时候:四种方式url拦截.注解.页面标签.代码级别,当需要验证权限会调用realm中的授权方法 Shiro框架内部整合好缓存管理器, ...
- RTX这种东西究竟有什么价值?
我在第一家公司工作的时候,同事沟通用的就是RTX,第一感觉就是这么简单的软件也能卖钱? 这种东西有啥价值啊?不就是个没广告蓝色UI的qq吗? 还是那句话,当你已经习惯了一个东西之后,你不会感觉到他的价 ...
- Linux系统命令Top/free的使用及参数详解
1.作用 top命令用来显示执行中的程序进程,使用权限是所有用户. 2.格式 top [-] [d delay] [q] [c] [S] [s] [i] [n] 3.主要参数 d:指定更新的间隔,以秒 ...
- 第4章 jQuery中的事件和动画
4.1 jQuery中的事件 4.1.1 加载DOM jQuery就是用 `$(document).ready()方法来代替传统JavaScript的window.onload方法的. 1.执行时机 ...
- Java50道经典习题-程序48 数字加密
题目:某个公司采用公用电话传递数据,数据是四位的整数,在传递过程中是加密的,加密规则如下:每位数字都加上5,然后用和除以10的余数代替该数字,再将第一位和第四位交换,第二位和第三位交换.分析:例如原始 ...