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 }
  • 相关阅读:
    读Pyqt4教程,带你入门Pyqt4 _009
    [Objective-C] 006_Protocol(协议)
    [JavaWeb基础] 003.JAVA访问Mysql数据库
    keras学习笔记-bili莫烦
    CentOS7安装codeblocks
    [转] Linux多线程编程之pthread
    [转] C++ 的关键字(保留字)完整介绍
    如何生成红黑树?一步一步画给你看(从二叉查找树到2-3树再到红黑树)
    C++标准库(体系结构与内核分析)(侯捷第二讲)(OOP GP、分配器、容器之间关系、list、萃取机、vector、array、deque、stack、queue、RB-tree、set、multiset、map、multimap)
    C++标准库(体系结构与内核分析)(侯捷第一讲)(标准库介绍、STL、六大部件、算法、容器分类、Array、Vector、List、Forward-List、Deque、stack、queue、multiset、multimap、分配器)
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6131360.html
Copyright © 2011-2022 走看看