题意
题意是给你一张 NMNMNM 的图,每个点有黑色和白色,初始全为白色,每次可以把一个相同颜色的连续区域染色,求最少的染色次数;(n,m<=50)
题解
转化为最短路。对于每一个点与它相邻的相同颜色的点连权值为0的边,对于颜色不同的点连权值为1的点。从每一个点跑单源最短路,把到W点的距离和到B点的距离+1取min作为此点的答案,最后把每一个点的答案取max就是答案。
对于能直接到达的两个颜色相同的点显然只用涂一次,如果不同就要再涂一次,所以这样建图。为了特判全是黑色的情况,所以到B点的距离要加一。显然,这样对于其他情况没有影响。
1 #include2 #include 3 #include 4 #include 5 #include 6 #include 7 using namespace std; 8 const int INF=0x3f3f3f3f; 9 int n,m;10 char s[600][600];11 int ans=INF;12 int dis[30000],vis[30000],head[30000],cnt;13 struct edge{14 int to,nxt,w;15 }e[900000];16 void add(int u,int v,int w){17 cnt++;18 e[cnt].nxt=head[u];19 e[cnt].to=v;20 e[cnt].w=w;21 head[u]=cnt;22 } 23 int zb(int x,int y){24 return (x-1)*m+y;25 }26 void spfa(int ss){27 queue q;28 memset(dis,0x3f,sizeof(dis));29 dis[ss]=0;30 q.push(ss);31 vis[ss]=1;32 while(!q.empty()){33 int u=q.front();34 q.pop();35 vis[u]=0;36 for(int i=head[u];i;i=e[i].nxt){37 int v=e[i].to;38 if(dis[v]>dis[u]+e[i].w){39 dis[v]=dis[u]+e[i].w;40 if(vis[v]==0){41 vis[v]=1;42 q.push(v);43 }44 }45 }46 }47 int tmp=-1; 48 for(int i=1;i<=n*m;i++){49 if(s[(i-1)/m+1][(i-1)%m+1]=='B')tmp=max(tmp,dis[i]+1);50 else tmp=max(tmp,dis[i]);51 }52 ans=min(ans,tmp);53 }54 int main(){55 scanf("%d%d",&n,&m);56 for(int i=1;i<=n;i++)57 for(int j=1;j<=m;j++){58 cin>>s[i][j];59 }60 for(int i=1;i<=n;i++)61 for(int j=1;j<=m;j++){62 if(i>1)add(zb(i,j),zb(i-1,j),(s[i][j]!=s[i-1][j]));63 if(i 1)add(zb(i,j),zb(i,j-1),(s[i][j]!=s[i][j-1]));65 if(j