zoukankan      html  css  js  c++  java
  • 题解CF37E Trial for Chief

    题目:CF37E Trial for Chief

    这题非常巧妙。这里可以把一块连续区域染色很容易误导做题者。实际上这题的做法是转换成最短路。
    为什么呢?仔细想一想,对于这个点,和它同一次涂色的点一定是和它上下左右相邻的点连通的点。
    每新涂色一次贡献就要+1,那么什么时候新涂色一次呢?显然是这个点和它相邻的点颜色不同的时候就要新涂色一次。
    于是我们对于每个点和它上下左右的点连边,当两点颜色相同时边权为0,否则为1。然后我们以每个点开头跑一边dij,记录一下所有黑色点的最大路径长度,答案就是这些长度的最小值+1。
    为什么是黑色呢?因为初始是白色。
    为什么要+1呢?因为你默认起点的dis是0,但那实际上是第一次涂色。特殊情况就是全为白色,所以Maxn初始值为-1。
     1 #include<stdio.h>
     2 #include<queue>
     3 #define it register int
     4 #define il inline
     5 using namespace std;
     6 const int N=1000005;
     7 const int dx[]={0,0,1,-1};
     8 const int dy[]={1,-1,0,0};
     9 char s[55][55];
    10 int n,m,ans,d[N],h[N],nxt[N],adj[N],w[N],t,cnt,bh[55][55];
    11 struct ky{
    12     int u,dis;
    13     bool operator<(const ky &p)const{
    14         return dis>p.dis;
    15     }
    16 };
    17 priority_queue<ky> q;
    18 il void add(it u,it v,it x){
    19     nxt[++t]=h[u],h[u]=t,adj[t]=v,w[t]=x;
    20 }
    21 il int Min(it p,it q){
    22     return p<q?p:q;
    23 }
    24 il int Max(it p,it q){
    25     return p>q?p:q;
    26 }
    27 il void dij(it st){
    28     for(it i=1;i<=cnt;++i) d[i]=1e9;
    29     d[st]=0,q.push((ky){st,0});
    30     register ky top;
    31     while(!q.empty()){
    32         top=q.top();q.pop();
    33         if(top.dis^d[top.u]) continue;
    34         for(it i=h[top.u],j;i;i=nxt[i])
    35             if(d[j=adj[i]]>top.dis+w[i]) d[j]=top.dis+w[i],q.push((ky){j,d[j]});
    36     }
    37     it maxn=-1;
    38     for(it i=1;i<=n;++i)
    39         for(it j=1;j<=m;++j)
    40             if(s[i][j]=='B') maxn=Max(maxn,d[bh[i][j]]); 
    41     ans=Min(ans,maxn+1);
    42 }
    43 int main(){
    44     scanf("%d%d",&n,&m);
    45     for(it i=1;i<=n;++i) scanf("%s",s[i]+1);
    46     for(it i=1;i<=n;++i)
    47         for(it j=1;j<=m;++j)
    48             bh[i][j]=++cnt;
    49     for(it i=1,tx,ty;i<=n;++i)
    50         for(it j=1;j<=m;++j)
    51             for(it k=0;k<4;++k){
    52                 tx=i+dx[k],ty=j+dy[k];
    53                 if(tx<1||tx>n||ty<1||ty>m) continue;
    54                 add(bh[i][j],bh[tx][ty],s[i][j]!=s[tx][ty]);
    55             }
    56     ans=0x7fffffff;
    57     for(it i=1;i<=cnt;++i) dij(i);
    58     printf("%d",ans);
    59     return 0;
    60 }
    View Code
  • 相关阅读:
    JS语法转换-ES6转ES5
    百度编辑器的初步使用
    github使用的小坑 处理
    关于input的检验问题
    一些代码规范(收集)
    jquery源码解析日常
    重操JS旧业第九弹:函数表达式
    重操JS旧业第八弹:面向对象与继承
    重操JS旧业第七弹:面向对象与对象创建
    重操JS旧业第六弹:基本类型包装
  • 原文地址:https://www.cnblogs.com/Kylin-xy/p/11798494.html
Copyright © 2011-2022 走看看