码迷,mamicode.com
首页 > 其他好文 > 详细

雪场缆车——染色

时间:2019-10-08 23:38:01      阅读:100      评论:0      收藏:0      [点我收藏+]

标签:一个   etc   ios   ||   read   tin   int   简单的   cst   

题目描述

约翰的表哥罗恩生活在科罗拉多州.他近来打算教他的奶牛们滑雪,但是奶牛们非常害羞, 不敢在游人如织的度假胜地滑雪.没办法,他只好自己建滑雪场了. 罗恩的雪场可以划分为$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);
}

 

 

 

  

雪场缆车——染色

标签:一个   etc   ios   ||   read   tin   int   简单的   cst   

原文地址:https://www.cnblogs.com/THRANDUil/p/11638503.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!