题意:一个网格上有一些障碍和$3$个在网格边界上的棋子,你要添加一些障碍使得没有两个棋子四连通,问最少添加多少个障碍

官方题解——一张图教你做人...

三个棋子将网格边界分成三段,添加障碍后网格中一定存在一个点使得它可以到这三段(只走障碍的路径,八连通)

所以找出这三段后分别以它们为起点跑最短路即可,经过障碍权值为$0$,经过空地权值为$1$

#include<stdio.h>
#include<queue>
#include<string.h>
#include<vector>
#include<string>
using namespace std;
int h[410],nex[7010],to[7010],v[7010],M;
void add(int a,int b,int c){
	M++;
	to[M]=b;
	v[M]=c;
	nex[M]=h[a];
	h[a]=M;
}
int dis[410];
struct pr{
	int x,d;
	pr(int u=0){x=u;d=dis[u];}
}t;
bool operator<(pr a,pr b){return a.d>b.d;}
priority_queue<pr>q;
void dijk(int x){
	int i;
	memset(dis,63,sizeof(dis));
	dis[x]=0;
	q.push(x);
	while(!q.empty()){
		t=q.top();
		q.pop();
		x=t.x;
		if(t.d!=dis[x])continue;
		for(i=h[x];i;i=nex[i]){
			if(dis[x]+v[i]<dis[to[i]]){
				dis[to[i]]=dis[x]+v[i];
				q.push(to[i]);
			}
		}
	}
}
const int g4[4][2]={{0,1},{0,-1},{1,0},{-1,0}},g8[8][2]={{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
int d[3][410],n,m;
vector<string>mp;
bool ok(int x,int y){
	return 0<=x&&x<n&&0<=y&&y<m;
}
bool edge(int x,int y){
	return ok(x,y)&&(x==0||x==n-1||y==0||y==m-1);
}
void dfs(int fx,int fy,int x,int y,int s){
	int i,tx,ty;
	if(mp[x][y]=='A')return;
	add(s,x*m+y+1,0);
	add(x*m+y+1,s,mp[x][y]=='.');
	for(i=0;i<4;i++){
		tx=x+g4[i][0];
		ty=y+g4[i][1];
		if((tx!=fx||ty!=fy)&&edge(tx,ty))dfs(x,y,tx,ty,s);
	}
}
class Block3Checkers{
	public:
		int blockThem(vector<string>mp){
			int i,j,k,x,y,f,s[3],ans;
			::mp=mp;
			n=mp.size();
			m=mp[0].length();
			s[0]=n*m+1;
			s[1]=n*m+2;
			s[2]=n*m+3;
			f=0;
			for(i=0;i<m;i++){
				if(mp[0][i]=='A'){
					if((i&&mp[0][i-1]=='A')||(i<m-1&&mp[0][i+1]=='A')||mp[1][i]=='A')return 100;
					if(i==0)
						dfs(0,0,1,0,s[f]);
					else
						dfs(0,i,0,i-1,s[f]);
					f++;
				}
				if(mp[n-1][i]=='A'){
					if((i&&mp[n-1][i-1]=='A')||(i<m-1&&mp[n-1][i+1]=='A')||mp[n-2][i]=='A')return 100;
					if(i==m-1)
						dfs(n-1,m-1,n-2,m-1,s[f]);
					else
						dfs(n-1,i,n-1,i+1,s[f]);
					f++;
				}
			}
			for(i=1;i<n-1;i++){
				if(mp[i][0]=='A'){
					if(mp[i-1][0]=='A'||mp[i+1][0]=='A')return 100;
					dfs(i,0,i+1,0,s[f]);
					f++;
				}
				if(mp[i][m-1]=='A'){
					if(mp[i-1][m-1]=='A'||mp[i+1][m-1]=='A')return 100;
					dfs(i,m-1,i-1,m-1,s[f]);
					f++;
				}
			}
			for(i=0;i<n;i++){
				for(j=0;j<m;j++){
					if(mp[i][j]!='A'){
						for(k=0;k<8;k++){
							x=i+g8[k][0];
							y=j+g8[k][1];
							if(ok(x,y)&&mp[x][y]!='A')add(i*m+j+1,x*m+y+1,mp[i][j]=='.');
						}
					}
				}
			}
			for(i=0;i<3;i++){
				dijk(s[i]);
				memcpy(d[i],dis,sizeof(dis));
			}
			ans=n*m;
			for(i=0;i<n;i++){
				for(j=0;j<m;j++){
					if(mp[i][j]!='A'){
						x=i*m+j+1;
						ans=min(ans,d[0][x]+d[1][x]+d[2][x]+(mp[i][j]=='.'));
					}
				}
			}
			return ans;
		}
};
/*
int main(){
	vector<string>vt;
	char s[30];
	Block3Checkers cl;
	while(~scanf("%s",s))vt.push_back(s);
	printf("%d",cl.blockThem(vt));
}
*/

[TCO2013]Block3Checkers的更多相关文章

  1. [TCO2013]TrickyInequality

    $\newcommand{stirf}[2]{{{#1}\brack{#2}}}$$\newcommand{stirs}[2]{{{#1}\brace{#2}}}$题意:$\sum\limits_{i ...

  2. [TCO2013]LitPanels

    题意:一个$n\times m$的无色网格,你可以在其中选择两个$x\times y$的子矩形并在其中将其中任意的格子涂上颜色,问最终能得到多少种不同的网格 做这题会用到一个概念叫包围盒(boundi ...

  3. [TCO2013]DirectionBoard

    题意:给一个网格,每个格子有一个方向表示在这个格子上要往哪个方向走,你可以改变某些格子的方向,问最少多少次操作使得从任意格子出发都能回到这个格子 woc这都不会我还是回家种田去吧... 题目的要求是改 ...

随机推荐

  1. bzoj 1058 bst

    因为是数列的维护,所以我们可以考虑用splay来维护,每次在x插入的时候就在x+1前面插入就行了,然后用bst来维护两问的答案,但是应该会tle.我们来考虑这个问题的性质,首先因为这个数列没有删除操作 ...

  2. list互转datatable 支持Nullable转换

    /// <summary> /// list转datatable /// </summary> /// <param name="list">& ...

  3. js中的document.ready

    1.概念 表示在dom结构绘制完成后执行,可能DOM元素关联的部分并未加载完 2.写法 $(document).on("ready",function(){ }) $(docume ...

  4. xxx_initcall相关知识

    参考文件include/linux/init.h /* * Early initcalls run before initializing SMP. * * Only for built-in cod ...

  5. 33.Search in Rotated Sorted Array---二分变形---《剑指offer》面试题8

    题目链接 题目大意:在一个旋转数组中,判断给定的target是否存在于该旋转数组中.数组中没有重复数值.例子如下: 法一:二分.确定中间元素之后,就要判断下一步是遍历左数组还是遍历右数组.如果左数组有 ...

  6. 搭建selenium+python自动化环境

    1.安装python,下载地址:http://python.org---安装版本3.5.1 ps:自带setuptools和pip工具 2.然后,用pip安装开发Web App需要的第三方库:异步框架 ...

  7. 深度学习开源工具——caffe介绍

    本页是转载caffe的一个介绍,之前的页面图都down了,更新一下. 目录 简介 要点记录 提问 总结 简介 报告时间是北京时间 12月14日 凌晨一点到两点,主讲人是 Caffe 团队的核心之一 E ...

  8. 详解WordPress中简码格式标签编写的基本方法

    WordPress 简码是一种类似于论坛标签的东西,格式类似于把尖括号换成中括号的 Html 标签.简码很多人叫做短代码,但官方的翻译应该是简码,在这里纠正一下. 简码的开发的逻辑比较简单,主要就是添 ...

  9. 封装ajax支持get、post

    为什么要封装ajax,因为…… for(var i=0;i<20;i++){ $.ajax(……) } 的时候,整个页面都卡死了,于是,我开始找答案. 后来,找到了,就是jquery的ajax属 ...

  10. LoadRunner中常用函数参考手册

    基础篇1:LoadRunner中常用函数参考手册 常用函数列表 web_url web_submmit_form VS web_submmit_data VS web_custom_request w ...