雪场缆车——染色

Posted thranduil

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了雪场缆车——染色相关的知识,希望对你有一定的参考价值。

题目描述

约翰的表哥罗恩生活在科罗拉多州.他近来打算教他的奶牛们滑雪,但是奶牛们非常害羞, 不敢在游人如织的度假胜地滑雪.没办法,他只好自己建滑雪场了. 罗恩的雪场可以划分为$W列L行(1≤W≤500;1≤L≤500),每个方格有一个特定的高度H(O≤日≤9999).$奶牛可以在相临方格间滑雪,而且不能由低到高滑.  为了保证任意方格可以互通,罗恩打算造一些直达缆车.缆车很强大,可以连接任意两个方格,而且是双向的.而且同一个方格也可以造多台缆车. 但是缆车的建造费用贵得吓人,所以他希望造尽量少的缆车.那最少需要造多少台呢? 

思路

  首先看到这题感觉挺简单的,暴力$flood  fill$,然后直接根据颜色数贪心即可。后来我发现我还是太naive了。

  正解:要使整张图形成一个强联通分量,那么必须满足加边之后没有出度为0的点和入度为0的点,于是我们只需要把每个相同高度的地方先染色,然后暴力从高往低连边,统计入度和出度的个数。最后统计入度为0的颜色数和出度为0的颜色数,比一个max即可。

下面放上简单易懂的代码。

code

 

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<queue>
#include<map>
using namespace std;
const int N=510;
int a[N][N];
int n,m;
int col[N][N],color;
map<int,int>vis[N*N];

int dx[5]={0,0,1,-1};
int dy[5]={1,-1,0,0};
int in[N*N],out[N*N];

inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();}
    while(ch>=0&&ch<=9){x=x*10+ch-0;ch=getchar();}
    return x*f;
}

inline bool chk(int x,int y)
{
    return (x>=1&&x<=n&&y>=1&&y<=m);
}

inline void bfs1(int x,int y)
{
    color++;
    queue<int>q1,q2;
    col[x][y]=color;
    q1.push(x);q2.push(y);
    while(!q1.empty())
    {
        int xx=q1.front(),yy=q2.front();
        for(int i=0;i<4;i++)
        {
            x=xx+dx[i];y=yy+dy[i];
            if(!col[x][y]&&chk(x,y)&&a[xx][yy]==a[x][y])
            {
                q1.push(x);q2.push(y);
                col[x][y]=color;
            }
        }
        q1.pop();q2.pop();
    }
}

int main()
{
    m=read();n=read();
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
    a[i][j]=read();
    
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
    if(!col[i][j])bfs1(i,j);
    
    /*cout<<endl;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        cout<<col[i][j]<<" ";cout<<endl;
    }*/
    if(color==1){cout<<"0";return 0;}
    
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
    {
        for(int k=0;k<4;k++)
        {
            int x=i+dx[k],y=j+dy[k];
            if(!chk(x,y))continue;
            if(!vis[col[i][j]][col[x][y]]&&a[i][j]>a[x][y])
            {
                out[col[i][j]]++;
                in[col[x][y]]++;
                vis[col[i][j]][col[x][y]]=1;
                vis[col[x][y]][col[i][j]]=1;
            }
        }
    }            
                
    int ans1=0,ans2=0;
    for(int i=1;i<=color;i++)
    {
        if(!in[i])ans1++;
        if(!out[i])ans2++;
    }
    
    cout<<max(ans1,ans2);
}

 

 

 

  

以上是关于雪场缆车——染色的主要内容,如果未能解决你的问题,请参考以下文章

7.多关联双亲染色体片段代换系(CSSL)群体的代谢组分析

染色体基因芯片分析和第二代测序应用的区别

香港山顶缆车以全新面貌亮相,带游客登太平山顶俯瞰维多利亚港

BZOJ4254Aerial Tramway 树形DP

如何使用ChromHMM鉴定染色质状态

基于php+mysql的尧山滑雪场会员管理系统