转载请注明出处,谢谢http://blog.youkuaiyun.com/ACM_cxlove?viewmode=contents by---cxlove
这是2012年lartin america 的题目。
巨坑啊,练习的时候yobobobo一度认为正解是流。
其实 是这样的。。。
最终要使得整个图是连通的。
先数一下有几个连通子块。
总有一种方案调整档板,可以使得两个连通子块连通。
所以大概就是连通块的个数减一吧。
但是这题给的数据太蘑菇了。。。。
真没啥好说的题。。。。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
#define mp(a,b) make_pair(a,b)
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
int n;
char str[1000][1000];
bool flag[1000][1000];
int way[4][2]={0,1,0,-1,1,0,-1,0};
void bfs(int x,int y){
queue<pair<int,int> >que;
flag[x][y]=1;
que.push(mp(x,y));
while(!que.empty()){
pair<int,int>u=que.front(),v;
que.pop();
for(int i=0;i<4;i++){
x=u.first;y=u.second;
int xx=u.first+way[i][0];
int yy=u.second+way[i][1];
if(xx<0||yy<0||xx>=2*n||yy>=2*n+1||flag[xx][yy])
continue;
int x1=min(x,xx),x2=max(x,xx);
int y1=min(y,yy),y2=max(y,yy);
//左右移动
if(i<2){
if(y1&1){
if(x==0||x==2*n-1||str[x%2==0?x-1:x][(y-1)/2]=='H'){
que.push(mp(xx,yy));
flag[xx][yy]=1;
}
}
else{
if(y2==2*n||str[x&1?(x-1):x][y2/2]=='H'){
que.push(mp(xx,yy));
flag[xx][yy]=1;
}
}
}
else{
if(x1&1){
if(y==0||str[(x1%2==0?(x1-1):x1)][(y-1)/2]=='V'){
que.push(mp(xx,yy));
flag[xx][yy]=1;
}
}
else{
if(y==2*n||str[x1][y2/2]=='V') {
que.push(mp(xx,yy));
flag[xx][yy]=1;
}
}
}
}
}
}
int main(){
while(scanf("%d",&n)!=EOF){
int cnt=0;
memset(flag,false,sizeof(flag));
for(int i=0;i<2*n-1;i++)
scanf("%s",str[i]);
for(int i=0;i<2*n;i++){
for(int j=0;j<2*n+1;j++){
if(flag[i][j]) continue;
cnt++;
bfs(i,j);
}
}
printf("%d\n",cnt-1);
}
return 0;
}