引水入城(洛谷_1514)

这题好像是200几年的题,

主要就是贪心加bfs。

求出每一个点流出的水,能遍布哪一些。

有一个优化,就是,当前点要比左右两边都高,才遍历。

而且遍历完之后,最后一行一定是连续的区间,否则就是有位置不能被覆盖。

然后这题就转换成了区间覆盖问题,贪心求解。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
inline int read(){
    int t=1,num=0;char c=getchar();
    while(c>‘9‘||c<‘0‘){if(c==‘-‘)t=-1;c=getchar();}
    while(c>=‘0‘&&c<=‘9‘){num=num*10+c-‘0‘;c=getchar();}
    return num*t;
}
const int N=510;
const int xt[4]={-1,0,0,1};
const int yt[4]={0,-1,1,0};
int n,m,a[N][N],d[N][N],cov[N],cnt=0;
struct note{int x,y;};
struct edge{int l,r;}b[N];
void bfs(int s){
    memset(d,0,sizeof(d));
    queue<note> q;
    q.push((note){1,s});d[1][s]=1;
    while(!q.empty()){
        note t=q.front();q.pop();
        for(int j=0;j<4;j++){
            int x=t.x+xt[j],y=t.y+yt[j];
            if(x<1||y<1||x>n||y>m)continue;
            if(d[x][y]==0&&a[x][y]<a[t.x][t.y]){
                d[x][y]=1;q.push((note){x,y});
            }
        }
    }
    int f,t;f=t=-1;
    for(int i=1;i<=m;i++){
        if(f==-1&&d[n][i]==1)f=i;
        if(d[n][i]==1&&d[n][i+1]==0)t=i;
        cov[i]|=d[n][i];
    }
    if(f!=-1)b[++cnt].l=f,b[cnt].r=t;
}
bool cmp(edge i,edge j){return i.l<j.l;}
void tanxin(){
    int ans=1,s=1,nxt=1;
    sort(b+1,b+1+cnt,cmp);
    for(int i=1;i<=cnt;i++){
        if(b[i].l<=s)nxt=max(nxt,b[i].r);
        else{
            ans++;s=nxt+1;
            nxt=max(nxt,b[i].r);
        }
        if(nxt>=m)break;
    }
    printf("1\n%d",ans);
}
int main()
{
    n=read();m=read();
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            a[i][j]=read();
    if(a[1][1]>=a[1][2])bfs(1);
    for(int i=2;i<m;i++)
        if(a[1][i-1]<=a[1][i]&&a[1][i]>=a[1][i+1])
            bfs(i);
    if(a[1][m]>=a[1][m-1])bfs(m);
    int ans=0;
    for(int i=1;i<=m;i++)
        if(!cov[i])ans++;
    if(ans)printf("0\n%d",ans);
    else tanxin();
    return 0;
}

本文由Yzyet编写,网址为www.cnblogs.com/Yzyet。非Yzyet同意,禁止转载,侵权者必究。

时间: 2024-10-13 06:19:19

引水入城(洛谷_1514)的相关文章

CODEVS 1066/洛谷 P1514引水入城

1066 引水入城 2010年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政 区划十分特殊,刚好构成一个N行M列的矩形,如上图所示,其中每个格子都代表一座城 市,每座城市都有一个海拔高度. 为了使居民们都尽可能饮用到清澈的湖水,现在要在某些城市建造水利设施.水利设施 有两种,分别为蓄水厂和输水站.蓄水厂的功能是利用水泵将湖

洛谷 P1514 引水入城

P1514 引水入城 题目描述 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个N 行M 列的矩形,如上图所示,其中每个格子都代表一座城市,每座城市都有一个海拔高度. 为了使居民们都尽可能饮用到清澈的湖水,现在要在某些城市建造水利设施.水利设施有两种,分别为蓄水厂和输水站.蓄水厂的功能是利用水泵将湖泊中的水抽取到所在城市的蓄水池中. 因此,只有与湖泊毗邻的第1 行的城市可以建造蓄水厂.而输水站的功能则是通过输水管线利用高度落差,将湖水从高处向

NOIP2010 引水入城 题解

http://www.rqnoj.cn/problem/601 今天发现最小区间覆盖竟然是贪心,不用DP!于是我又找到这题出来撸了一发. 要找到最上面每个城市分别能覆盖最下面哪些城市,如果最下面有城市怎么都覆盖不到,就输出覆盖不到的城市数. 这样,最上面的城市能覆盖的最下面的城市一定是一个区间,不会从中间断开.因为如果断开了,那断开的这一部分怎么都没有水能流到了,可以按照覆盖不到处理.当全部能覆盖到的时候,才要用这些区间来算最小需要多少个起点城市,有覆盖不到的就不用这些区间了.居然,好像说得很复

luoguP1514 引水入城 x

P1514 引水入城 题目描述 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个N 行M 列的矩形,如上图所示,其中每个格子都代表一座城市,每座城市都有一个海拔高度. 为了使居民们都尽可能饮用到清澈的湖水,现在要在某些城市建造水利设施.水利设施有两种,分别为蓄水厂和输水站.蓄水厂的功能是利用水泵将湖泊中的水抽取到所在城市的蓄水池中. 因此,只有与湖泊毗邻的第1 行的城市可以建造蓄水厂.而输水站的功能则是通过输水管线利用高度落差,将湖水从高处向

引水入城(性质题)

引水入城(性质题) 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个N 行M 列的矩形.每座城市都有一个海拔高度.为了使居民们都尽可能饮用到清澈的湖水,现在要在某些城市建造水利设施.水利设施有两种,分别为蓄水厂和输水站.蓄水厂的功能是利用水泵将湖泊中的水抽取到所在城市的蓄水池中.因此,只有与湖泊毗邻的第1 行的城市可以建造蓄水厂.而输水站的功能则是通过输水管线利用高度落差,将湖水从高处向低处输送.故一座城市能建造输水站的前提,是存在比它海拔更

Luogu P1514 引水入城

题目描述 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个 \(N\) 行 \(\times M\) 列的矩形,如上图所示,其中每个格子都代表一座城市,每座城市都有一个海拔高度. 为了使居民们都尽可能饮用到清澈的湖水,现在要在某些城市建造水利设施.水利设施有两种,分别为蓄水厂和输水站.蓄水厂的功能是利用水泵将湖泊中的水抽取到所在城市的蓄水池中. 因此,只有与湖泊毗邻的第\(1\)行的城市可以建造蓄水厂.而输水站的功能则是通过输水管线利用高度落

CCF(引水入城:60分):最大流+ISAP算法

引水入城 201703-5 这从题目分析来看很像最大流的问题,只需要增加一个超级源点和一个超级汇点就可以按照题意连边再跑最大流算法. 因为数据量太大了,肯定会超时.但是没有想到可行的解决方法. #include<bits/stdc++.h> using namespace std; const long long INF=0XFFFFFFFF; const int maxn=4500016; /* run this program using the console pauser or add

Luogu_P1514 引水入城 记忆化搜索

Luogu_P1514 引水入城 ### 记忆化搜索 题目链接 题目的意思很好理解 考虑记忆化搜索 搜索第一行每个点能覆盖的区间 \(l[x][y]\)和\(r[x][y]\)分别表示点\((x,y)\)能覆盖的左右端点 转移自然是取\(\min\)和取\(\max\) 最后\(dfs\)完了统计一下最后一排的覆盖来看第一问 如果覆盖了就扫左右端点就行了 代码如下: #include<bits/stdc++.h> using namespace std; const int maxn=510;

[NOIP2010提高组]引水入城

题目:洛谷P1514.Vijos P1777.codevs1066. 题目大意:有一个$n×m$的矩阵,每个点都有一个高度,可以在第一行的任意点建立蓄水厂.现在要把水输到最后一行的所有点上,规定水只能流到高度比当前点小的点上.先让你判断能否输到所有点上,如能,输出最少建多少个蓄水厂:如不能,输出最多能输到几个点上. 解题思路:首先把第一行所有点塞进队列里,跑BFS,找出所有能到的点,然后判断能否输到最后一行所有点上.如果不能,输出最后一行能被输到的点的总数.如果能的话,我们依次把第一行每个点能输