zoj3781
zoj3781
赛场上堵在了缩点上emmmmm
把原始图相同颜色的方块缩成一个点,然后与它周围不同颜色的联通块连双向边,然后枚举每个点然后求最大深度的最小值
因为每次翻转都相当于深度+1(可以手动模拟一下
#include<iostream> #include<cstdio> #include<queue> #include<algorithm> #include<cmath> #include<ctime> #include<set> #include<map> #include<stack> #include<cstring> #define inf 2147483647 #define ls rt<<1 #define rs rt<<1|1 #define lson ls,nl,mid,l,r #define rson rs,mid+1,nr,l,r #define N 100010 #define For(i,a,b) for(register int i=a;i<=b;i++) #define p(a) putchar(a) #define g() getchar() using namespace std; int T; int n,m; int deep[1700]; char a[1700][1700]; bool b[1700][1700]; int col[1700][1700]; bool vis[1700][1700],v[1700]; int cnt; int ans; queue<int>q; struct node{ int n; node *next; }*e[1000000]; void in(int &x){ int y=1; char c=g();x=0; while(c<'0'||c>'9'){ if(c=='-')y=-1; c=g(); } while(c<='9'&&c>='0'){ x=(x<<1)+(x<<3)+c-'0';c=g(); } x*=y; } void o(int x){ if(x<0){ p('-'); x=-x; } if(x>9)o(x/10); p(x%10+'0'); } void clean(){ For(i,1,n) For(j,1,m){ vis[i][j]=0; col[i][j]=0; } For(i,1,n*m) For(j,1,n*m){ b[j][i]=0; b[i][j]=0; } For(i,1,1600) e[i]=0; cnt=0; ans=inf; } void push(int x,int y){ node *p; p=new node(); p->n=y; if(e[x]==0) e[x]=p; else{ p->next=e[x]->next; e[x]->next=p; } } void dfs(int x,int y,char f,int color){ if(x<1||y<1||x>n||y>m) return; if(vis[x][y]) return; if(a[x][y]==f){ vis[x][y]=1; col[x][y]=color; dfs(x-1,y,f,color); dfs(x,y-1,f,color); dfs(x,y+1,f,color); dfs(x+1,y,f,color); } } void ccc(int x,int y){ if(x<1||y<1||x>n||y>m) return; vis[x][y]=0; if(x-1>0&&!b[col[x][y]][col[x-1][y]]){ if(col[x][y]!=col[x-1][y]){ push(col[x][y],col[x-1][y]); push(col[x-1][y],col[x][y]); b[col[x][y]][col[x-1][y]]=1; b[col[x-1][y]][col[x][y]]=1; } if(vis[x-1][y]) ccc(x-1,y); } if(y-1>0&&!b[col[x][y]][col[x][y-1]]){ if(col[x][y]!=col[x][y-1]){ push(col[x][y],col[x][y-1]); push(col[x][y-1],col[x][y]); b[col[x][y]][col[x][y-1]]=1; b[col[x][y-1]][col[x][y]]=1; } if(vis[x][y-1]) ccc(x,y-1); } if(x+1<=n&&!b[col[x][y]][col[x+1][y]]){ if(col[x][y]!=col[x+1][y]){ push(col[x][y],col[x+1][y]); push(col[x+1][y],col[x][y]); b[col[x][y]][col[x+1][y]]=1; b[col[x+1][y]][col[x][y]]=1; } if(vis[x+1][y]) ccc(x+1,y); } if(y+1<=m&&!b[col[x][y]][col[x][y+1]]){ if(col[x][y]!=col[x][y+1]){ push(col[x][y],col[x][y+1]); push(col[x][y+1],col[x][y]); b[col[x][y]][col[x][y+1]]=1; b[col[x][y+1]][col[x][y]]=1; } if(vis[x][y+1]) ccc(x,y+1); } } void bfs(int x){ deep[x]=0; q.push(x); For(i,1,cnt) v[i]=0; v[x]=1; int ss=0; while(!q.empty()){ int t=q.front();q.pop(); for(node *i=e[t];i;i=i->next) if(!v[i->n]){ v[i->n]=1; q.push(i->n); deep[i->n]=deep[t]+1; ss=max(ss,deep[i->n]); } } ans=min(ss,ans); } int main(){ in(T); while(T--){ in(n);in(m); clean(); For(i,1,n) For(j,1,m) cin>>a[i][j]; For(i,1,n) For(j,1,m) if(!vis[i][j]) dfs(i,j,a[i][j],++cnt); ccc(1,1); For(i,1,cnt) bfs(i); o(ans);p('\n'); } return 0; }