转载请注明出处,谢谢http://blog.csdn.net/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; }