zoukankan      html  css  js  c++  java
  • CodeForces 37E Trial for Chief

    Time Limit: 2000MS   Memory Limit: 262144KB   64bit IO Format: %I64d & %I64u

    Description

    Having unraveled the Berland Dictionary, the scientists managed to read the notes of the chroniclers of that time. For example, they learned how the chief of the ancient Berland tribe was chosen.

    As soon as enough pretenders was picked, the following test took place among them: the chief of the tribe took a slab divided by horizontal and vertical stripes into identical squares (the slab consisted of N lines and M columns) and painted every square black or white. Then every pretender was given a slab of the same size but painted entirely white. Within a day a pretender could paint any side-linked set of the squares of the slab some color. The set is called linked if for any two squares belonging to the set there is a path belonging the set on which any two neighboring squares share a side. The aim of each pretender is to paint his slab in the exactly the same way as the chief’s slab is painted. The one who paints a slab like that first becomes the new chief.

    Scientists found the slab painted by the ancient Berland tribe chief. Help them to determine the minimal amount of days needed to find a new chief if he had to paint his slab in the given way.

    Input

    The first line contains two integers N and M (1 ≤ N, M ≤ 50) — the number of lines and columns on the slab. The next Nlines contain M symbols each — the final coloration of the slab. W stands for the square that should be painted white and B — for the square that should be painted black.

    Output

    In the single line output the minimal number of repaintings of side-linked areas needed to get the required coloration of the slab.

    Sample Input

    Input
    3 3
    WBW
    BWB
    WBW
    Output
    2
    Input
    2 3
    BBB
    BWB
    Output
    1

    Source

    逆向思维,从目标图开始将图染成初始图。每染一次色,联通块就会扩大,(类似colorflood)。

    那么如何计算代价?

    从每个点向四周连边,同色代价为0,异色代价为1,O(n^2)枚举起点,跑SPFA,看何时“最远代价最小”

    ↑注意特判:如果终态染成了全黑的图,因为初始图是全白,所以代价+1

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<queue>
     6 #define LL long long
     7 using namespace std;
     8 const int mx[5]={0,1,0,-1,0};
     9 const int my[5]={0,0,1,0,-1};
    10 const int mxn=18510;
    11 int read(){
    12     int x=0,f=1;char ch=getchar();
    13     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    14     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    15     return x*f;
    16 }
    17 struct edge{
    18     int v,nxt;
    19     int dis;
    20 }e[mxn<<1];
    21 int hd[mxn],mct=0;
    22 void add_edge(int u,int v,int d){
    23     e[++mct].v=v;e[mct].dis=d;e[mct].nxt=hd[u];hd[u]=mct;return;
    24 }
    25 int n,m;
    26 char mp[60][60];
    27 int id[60][60];
    28 bool inq[mxn];
    29 int dis[mxn];
    30 int SPFA(int s){
    31     memset(dis,0x3f,sizeof dis);
    32     queue<int>q;
    33     q.push(s);
    34     inq[s]=1;
    35     dis[s]=0;    
    36     while(!q.empty()){
    37         int u=q.front();q.pop();inq[u]=0;
    38         for(int i=hd[u];i;i=e[i].nxt){
    39             int v=e[i].v;
    40             if(dis[v]>dis[u]+e[i].dis){
    41                 dis[v]=dis[u]+e[i].dis;
    42                 if(!inq[v]){
    43                     inq[v]=1;
    44                     q.push(v);
    45                 }
    46             }
    47         }
    48     }
    49     int res=0;
    50     for(int i=1;i<=n;i++)
    51      for(int j=1;j<=m;j++)
    52          if(mp[i][j]=='W')res=max(res,dis[id[i][j]]);
    53          else res=max(res,dis[id[i][j]]+1);
    54     return res;
    55 }
    56 int main()
    57 {
    58     n=read();m=read();
    59     int i,j;
    60     for(i=1;i<=n;i++)
    61         scanf("%s",mp[i]+1);
    62     for(i=1;i<=n;i++)
    63      for(j=1;j<=m;j++)
    64          id[i][j]=(i-1)*m+j;
    65     for(i=1;i<=n;i++)
    66      for(j=1;j<=m;j++){
    67          for(int k=1;k<=4;k++){
    68              int nx=i+mx[k];
    69              int ny=j+my[k];
    70              if(nx<1 || nx>n || ny<1 || ny>m)continue;
    71              if(mp[i][j]==mp[nx][ny]){
    72                  add_edge(id[i][j],id[nx][ny],0);
    73                  add_edge(id[nx][ny],id[i][j],0);
    74             }
    75             else{
    76                  add_edge(id[i][j],id[nx][ny],1);
    77                  add_edge(id[nx][ny],id[i][j],1);
    78             }
    79          }
    80      }
    81     int ans=1e9;
    82     for(i=1;i<=n;i++)
    83      for(j=1;j<=m;j++){
    84         ans=min(ans,SPFA(id[i][j]));
    85      }
    86     printf("%d
    ",ans);
    87     return 0;
    88 }
  • 相关阅读:
    php中获取各种路径
    大型网站系统架构演化之路
    404、500、502等HTTP状态码介绍
    Linux 查看进程和删除进程
    mysql中FIND_IN_SET的使用方法
    PHP导出Excel 数字末尾变0或小数点解决办法
    PHP API接口测试小工具
    要慎用mysql的enum字段的原因
    mysql 导入&导出sql文件
    Linux下php安装memcache扩展
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6131360.html
Copyright © 2011-2022 走看看