zoukankan      html  css  js  c++  java
  • vijos1777 引水入城

    描述

    在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠。该国的行政区划十分特殊,刚好构成一个N行M列的矩形,其中每个格子都代表一座城市,每座城市都有一个海拔高度。

    为了使居民们都尽可能饮用到清澈的湖水,现在要在某些城市建造水利设施。水利设施有两种,分别为蓄水厂和输水站。蓄水厂的功能是利用水泵将湖泊中的水抽取到所在城市的蓄水池中。因此,只有与湖泊毗邻的第1行的城市可以建造蓄水厂。而输水站的功能则是通过输水管线利用高度落差,将湖水从高处向低处输送。故一座城市能建造输水站的前提,是存在比它海拔更高且拥有公共边的相邻城市,已经建有水利设施。

    由于第N行的城市靠近沙漠,是该国的干旱区,所以要求其中的每座城市都建有水利设施。那么,这个要求能否满足呢?如果能,请计算最少建造几个蓄水厂;如果不能,求干旱区中不可能建有水利设施的城市数目。

    格式

    输入格式

    输入文件的每行中两个数之间用一个空格隔开。

    输入的第一行是两个正整数N和M,表示矩形的规模。

    接下来N行,每行M个正整数,依次代表每座城市的海拔高度。

    输出格式

    输出有两行。如果能满足要求,输出的第一行是整数1,第二行是一个整数,代表最少建造几个蓄水厂;如果不能满足要求,输出的第一行是整数0,第二行是一个整数,代表有几座干旱区中的城市不可能建有水利设施。

    样例1

    样例输入1[复制]

     
    2 5
    9 1 5 4 3
    8 7 6 1 2

    样例输出1[复制]

     
    1
    1

    限制

    每个测试点1s

    提示

    本题共有10个测试数据,每个数据的范围如下表所示:
    测试数据编号 能否满足要求 N M
    1 不能 ≤ 10 ≤ 10
    2 不能 ≤ 100 ≤ 100
    3 不能 ≤ 500 ≤ 500
    4 能 = 1 ≤ 10
    5 能 ≤ 10 ≤ 10
    6 能 ≤ 100 ≤ 20
    7 能 ≤ 100 ≤ 50
    8 能 ≤ 100 ≤ 100
    9 能 ≤ 200 ≤ 200
    10 能 ≤ 500 ≤ 500
    对于所有的10个数据,每座城市的海拔高度都不超过10^6。

    来源

    noip2010提高组复赛

     
    好久没有发题解了啊……
    这是NOIP之前复习的时候做的原题
    首先从上到下一遍bfs,判断是否有不能被覆盖的城市
    这样做完保证一定有解了
    然后一个蓄水厂能覆盖的城市一定是一个连续的区间(反证法)
    因此再从下到上一遍bfs算出每个蓄水厂能覆盖的城市的左右端点
    然后变成线段覆盖了……贪心搞掉
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #include<deque>
    #include<set>
    #include<map>
    #include<ctime>
    #define LL long long
    #define inf 0x7ffffff
    #define pa pair<int,int>
    #define pi 3.1415926535897932384626433832795028841971
    using namespace std;
    const int mx[4]={1,0,-1,0};
    const int my[4]={0,1,0,-1};
    inline LL read()
    {
        LL 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;
    }
    int n,m,t,w,len;
    int a[510][510];
    int l[510][510];
    int r[510][510];
    bool mrk[510][510];
    int qx[250010];
    int qy[250010];
    struct seg{
    	int l,r;
    }d[1000];
    bool operator <(const seg &a,const seg &b)
    {
    	return a.l<b.l||a.l==b.l&&a.r<b.r;
    }
    inline void bfs1()
    {
    	while(t<w)
    	{
    		int nx=qx[++t];
    		int ny=qy[t];
    		for (int k=0;k<4;k++)
    		{
    			int wx=nx+mx[k],wy=ny+my[k];
    			if (wx<1||wx>n||wy<1||wy>m||mrk[wx][wy])continue;
    			if (a[wx][wy]>=a[nx][ny])continue;
    			qx[++w]=wx;
    			qy[w]=wy;
    			mrk[wx][wy]=1;
    		}
    	}
    }
    inline void bfs2(int dat[510][510],int x,int y)
    {
    	t=0;w=1;
    	qx[1]=x;
    	qy[1]=y;
    	dat[x][y]=y;
    	while (t<w)
    	{
    		int nx=qx[++t];
    		int ny=qy[t];
    		mrk[nx][ny]=1;
    		for (int k=0;k<4;k++)
    		{
    			int wx=nx+mx[k]; 
    			int wy=ny+my[k];
    			if (wx<1||wx>n||wy<1||wy>m||dat[wx][wy])continue;
    			if (a[wx][wy]<=a[nx][ny])continue;
    			dat[wx][wy]=dat[nx][ny];
    			qx[++w]=wx;
    			qy[w]=wy;
    		}
    	}
    }
    int main()
    {
    	n=read();m=read();
    	for (int i=1;i<=n;i++)
    	  for(int j=1;j<=m;j++)
    	    a[i][j]=read();
    	for (int i=1;i<=m;i++)
    	{
    		qx[++w]=1;
    		qy[w]=i;
    		mrk[1][i]=1;
    	}
    	bfs1();
    	int tot=0;
    	for (int i=1;i<=m;i++)
    	  if (!mrk[n][i])tot++;
    	if (tot)
    	{
    		printf("0
    %d
    ",tot);
    		return 0;
    	}
    	memset(mrk,0,sizeof(mrk));
    	for (int i=1;i<=m;i++)if (!l[n][i])bfs2(l,n,i);
    	for (int i=m;i>=1;i--)if (!r[n][i])bfs2(r,n,i);
    	for (int i=1;i<=m;i++)
    	  if (mrk[1][i])
    	  {
    	  	d[++len].l=l[1][i];
    	  	d[len].r=r[1][i];
    	  }
    	sort(d+1,d+len+1);
    	int now=0,ned=0,mx=0;
    	for (int i=1;i<=len;i++)
    	{
    		if(d[i].l<=now+1)mx=max(mx,d[i].r);
    		else now=mx,ned++,mx=max(mx,d[i].r);
    	}
    	if(now!=m)ned++;
    	printf("1
    %d
    ",ned);
    }
    

      

    ——by zhber,转载请注明来源
  • 相关阅读:
    C++结构体成员列表初始化
    hdu-3790-最短路径问题(Dijkstra)
    hdu--1878--欧拉回路(并查集判断连通,欧拉回路模板题)
    nyoj-1278-Prototypes analyze(二叉排序树模板)
    hdu-5183-Negative and Positive (NP)(hash模板)
    nyoj-130-相同的雪花(hash)
    详细介绍C++STL:unordered_map
    NYOJ-626-intersection set(二分查找)
    hdoj-2141-Can you find it?(二分查找)
    HDU-1232-畅通工程(并查集)
  • 原文地址:https://www.cnblogs.com/zhber/p/4093492.html
Copyright © 2011-2022 走看看