zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    CDN是如何工作的?
    JQuery UI的拖拽功能
    .net/C#开源操作系统学习系列
    [开源]KJFramework.Message 智能二进制消息框架 新能力
    [ASP.NET MVC]通过对HtmlHelper扩展简化“列表控件”的绑定
    Sencha Touch 2 官方文档翻译之 Managing Dependencies with MVC(管理MVC依赖项)
    Node.JS环境搭建手顺(无脑操作)
    找到拥有相同标签的用户对
    《算法导论》
    Controller的激活
  • 原文地址:https://www.cnblogs.com/Xu-daxia/p/9383168.html
Copyright © 2011-2022 走看看