[SRM570]TheTiles
题意:给一个$n\times m$的网格,对这个网格黑白染色,左上角为黑色。现在要用一些大小为$3$的L型图形覆盖这个网格,要求不能重复覆盖同一个格子,不能覆盖到障碍,L型可以进行旋转,但转角处格子必须为黑色,求最多能覆盖多少个L型图形
人生第一次上TC做题2333,最近机房网络不太稳定,lantern也经常崩,所以做这道题用了十几分钟才成功提交一次==
无论怎么旋转L型,两个白格必定不在同一行
所以$S$向奇数行白格连边,奇数行白格向相邻黑格连边,黑格向相邻偶数行白格连边,偶数行白格向$T$连边,这样跑最大流就对应着许多L型图形
为了保证每个格子最多被用一次,拆点连边限制流量即可
#include<stdio.h>
#include<string.h>
#include<vector>
#include<string>
using namespace std;
const int inf=2147483647;
int min(int a,int b){return a<b?a:b;}
int h[5010],cur[5010],nex[30010],to[30010],cap[30010],dis[5010],q[5010],M=1,S,T;
void add(int a,int b,int c){
M++;
to[M]=b;
cap[M]=c;
nex[M]=h[a];
h[a]=M;
M++;
to[M]=a;
cap[M]=0;
nex[M]=h[b];
h[b]=M;
}
bool bfs(){
int head,tail,x,i;
memset(dis,-1,sizeof(dis));
head=tail=1;
q[1]=S;
dis[S]=0;
while(head<=tail){
x=q[head];
head++;
for(i=h[x];i;i=nex[i]){
if(cap[i]&&dis[to[i]]==-1){
dis[to[i]]=dis[x]+1;
if(to[i]==T)return 1;
tail++;
q[tail]=to[i];
}
}
}
return 0;
}
int dfs(int x,int flow){
if(x==T)return flow;
int i,f;
for(i=cur[x];i;i=nex[i]){
if(cap[i]&&dis[to[i]]==dis[x]+1){
f=dfs(to[i],min(flow,cap[i]));
if(f){
cap[i]-=f;
cap[i^1]+=f;
if(cap[i])cur[x]=i;
return f;
}
}
}
dis[x]=-1;
return 0;
}
int dicnic(){
int ans=0,tmp;
while(bfs()){
memcpy(cur,h,sizeof(h));
while(1){
tmp=dfs(S,inf);
if(tmp==0)break;
ans+=tmp;
}
}
return ans;
}
const int gx[4]={1,-1,0,0},gy[4]={0,0,1,-1};
char s[50][50];
int n,m;
int p(int x,int y){return(x-1)*m+y;}
int in(int x,int y){return p(x,y)*2-1;}
int ou(int x,int y){return p(x,y)<<1;}
int col(int x,int y){
if(~(x+y)&1)return 2;
return(~x&1)*2+1;
}
bool ok(int x,int y){return 0<x&&x<=n&&0<y&&y<=m&&s[x][y]=='.';}
class TheTilesDivOne{
public:
int find(vector<string>board){
int i,j,k,x,y;
n=board.size();
m=board[0].length();
for(i=1;i<=n;i++)strcpy(s[i]+1,board[i-1].c_str());
S=n*m*2+1;
T=n*m*2+2;
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
if(s[i][j]=='.'){
add(in(i,j),ou(i,j),1);
if(col(i,j)==1)add(S,in(i,j),1);
if(col(i,j)==3)
add(ou(i,j),T,1);
else{
for(k=0;k<4;k++){
x=i+gx[k];
y=j+gy[k];
if(ok(x,y)&&col(i,j)+1==col(x,y))add(ou(i,j),in(x,y),1);
}
}
}
}
}
return dicnic();
}
};
/*
vector<string>v;
TheTilesDivOne test;
char str[50];
int main(){
int n,m,i;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
scanf("%s",str);
v.push_back(str);
}
printf("%d",test.find(v));
}
*/
辣鸡TC连warning都不给过,差评==
[SRM570]TheTiles的更多相关文章
- Topcoder SRM570 900 CurvyonRails
题意:给定一个网格,一些格子是障碍不用管,剩余的格子是城市,你可以修建铁路,铁路的形状可以是直的或者弯的,也就是说可以以这个点为节点连接它四联通的其中两个方块.要求用一个或多个环来覆盖所有城市.对于有 ...
- Topcoder SRM570 D1L3 CurvyonRails
几个样例: 5 5wCCwwwCC....w......www..wReturns: 0 3 3C.w....C.Returns: 1 21 20CC..CCCw.CwC..CC.w.CC.CCCwC ...
随机推荐
- weblogic的安装和注意的问题以及在idea怎么用weblogic启动一个web服务
第一步下载weblogic: 大家可以通过我的网盘下载weblogic,地址如下 https://pan.baidu.com/s/1NkZ_Gd-xfim5YGcdtjYoUw 第二步安装weblog ...
- java注解(Annotation)的简单介绍
注解你可以理解为一个特殊的类,或者接口其自定义个格式形如 public @interface 注解名(){ //注解的属性,特别提醒当注解的属性为value时,在对其赋值时,可以不写value,而直接 ...
- C ------ 标准函数介绍
sprintf() 函数原型:int sprintf( char *buffer, const char *format [, argument] ... ); 功能介绍: 1.把一个字符串赋值(拷贝 ...
- HDU1272---(并查集)简单应用
http://acm.hdu.edu.cn/showproblem.php?pid=1272 小希的迷宫 Time Limit: 2000/1000 MS (Java/Others) Memor ...
- 【洛谷 P3834】 可持久化线段树1(主席树)
题目链接 主席树=可持久化权值线段树. 如果你不会可持久化线段树,请右转 如果你不会权值线段树,请自行脑补,就是线段树维护值域里有多少个数出现. 可持久化线段树是支持查询历史版本的. 我们对每个数都进 ...
- Swift学习三
http://blog.csdn.net/kuloveyouwei/article/details/36005299 Swift 提供两种集合类型来存储集合,数组和字典.数组是一个同类型的序列化列表集 ...
- ZigBee MAC层(上)
1. 介绍 ZigBee MAC层,即IEEE 802.15.4 MAC层,这里主要介绍了802.15.4-2003版本 MAC层处理所有对物理无线信道的访问控制,并负责下面的任务 - 为协调器生成网 ...
- 安全测试===Mysql 注入技巧学习 MySQL注入技巧(2)
原文地址:http://websec.files.wordpress.com/2010/11/sqli2.pdf 0x00.介绍 也可以参考瞌腄龙的mysql注入科普:http://drops.woo ...
- 原创 gif png bmp jeg 显示方法
/// <summary> /// 注意不要忘记引用那几个图片单元哦,除了bmp格式不需要引用任何单元, /// 其它图片格式都需要引用对应的图片单元 /// png ---> Vc ...
- selenium 3.0鼠标事件 (java代码)
注意:ActionChains下相关方法在当前的firefox不工作,建议使用谷歌浏览器. public static void main(String[] args) throws Interrup ...