Bzoj3041 水叮当的舞步

时间:2022-05-21 03:41:25

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 132  Solved: 75

Description

水叮当得到了一块五颜六色的格子形地毯作为生日礼物,更加特别的是,地毯上格子的颜色还能随着踩踏而改变。
为了讨好她的偶像虹猫,水叮当决定在地毯上跳一支轻盈的舞来卖萌~~~
地毯上的格子有N行N列,每个格子用一个0~5之间的数字代表它的颜色。
水叮当可以随意选择一个0~5之间的颜色,然后轻轻地跳动一步,左上角的格子所在的联通块里的所有格子就会变成她选择的那种颜色。这里连通定义为:两个格子有公共边,并且颜色相同。
由于水叮当是施展轻功来跳舞的,为了不消耗过多的真气,她想知道最少要多少步才能把所有格子的颜色变成一样的。

Input

每个测试点包含多组数据。
每组数据的第一行是一个整数N,表示地摊上的格子有N行N列。
接下来一个N*N的矩阵,矩阵中的每个数都在0~5之间,描述了每个格子的颜色。
N=0代表输入的结束。

Output

对于每组数据,输出一个整数,表示最少步数。

Sample Input

2
0 0
0 0
3
0 1 2
1 1 2
2 2 1
0

Sample Output

0
3

对于100%的数据,N<=8,每个测试点不多于20组数据。

HINT

 

Source

DFS+IDA星

网络流写累了换换口味

其实就是Flood it : http://www.cnblogs.com/SilverNebula/p/5858410.html

 /*by SilverN*/
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<vector>
using namespace std;
const int mx[]={,,,-,};
const int my[]={,,,,-};
const int mxn=;
int read(){
int x=,f=;char ch=getchar();
while(ch<'' || ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>='' && ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,ans;
int mp[mxn][mxn];
int vis[mxn];
int mark[mxn][mxn];
int get(){//估价
int cnt=;
memset(vis,,sizeof vis);
for(int i=;i<=n;i++){
for(int j=;j<=n;j++){
if(!vis[mp[i][j]] && mark[i][j]!=){
vis[mp[i][j]]=;
cnt++;
}
}
}
return cnt;
}
void fill(int x,int y,int co){
mark[x][y]=;
for(int i=;i<=;i++){
int nx=x+mx[i];
int ny=y+my[i];
if(nx< || nx>n || ny< ||ny>n || mark[nx][ny]==)continue;
mark[nx][ny]=;
if(mp[nx][ny]==co)fill(nx,ny,co);
}
return;
}
int change(int co){
bool cnt=;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++){
if(mark[i][j]== && mp[i][j]==co){
fill(i,j,co);
cnt=;
}
}
return cnt;
}
void DFS(int res,int lim){
int tmp=get();
if(!tmp){ans=res;return;}
if(res+tmp>lim)return;
if(ans<)return;
int cpy[mxn][mxn];
for(int i=;i<=;i++){
memcpy(cpy,mark,sizeof mark);
if(change(i))DFS(res+,lim);
memcpy(mark,cpy,sizeof cpy);
}
return;
}
int main(){
int i,j;
while(scanf("%d",&n) && n){
memset(mark,,sizeof mark);
ans=;
for(i=;i<=n;i++)
for(j=;j<=n;j++)
mp[i][j]=read();
fill(,,mp[][]);
for(i=;i;i++){
DFS(,i);
if(ans<){
printf("%d\n",ans);
break;
}
}
}
return ;
}