CF37E Trial for Chief(最短路)

题意

题意是给你一张 NMNMNM 的图,每个点有黑色和白色,初始全为白色,每次可以把一个相同颜色的连续区域染色,求最少的染色次数;(n,m<=50)

题解

转化为最短路。对于每一个点与它相邻的相同颜色的点连权值为0的边,对于颜色不同的点连权值为1的点。从每一个点跑单源最短路,把到W点的距离和到B点的距离+1取min作为此点的答案,最后把每一个点的答案取max就是答案。

对于能直接到达的两个颜色相同的点显然只用涂一次,如果不同就要再涂一次,所以这样建图。为了特判全是黑色的情况,所以到B点的距离要加一。显然,这样对于其他情况没有影响。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<queue>
 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<int> 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<n)add(zb(i,j),zb(i+1,j),(s[i][j]!=s[i+1][j]));
64             if(j>1)add(zb(i,j),zb(i,j-1),(s[i][j]!=s[i][j-1]));
65             if(j<m)add(zb(i,j),zb(i,j+1),(s[i][j]!=s[i][j+1]));
66         }
67     for(int i=1;i<=n*m;i++){
68         spfa(i);
69     }
70     printf("%d",ans);
71     return 0;
72 }
View Code
原文地址:https://www.cnblogs.com/Xu-daxia/p/9383168.html