Noip 2010 引水入城

题目链接:https://vijos.org/p/1777

思路:网上的大神思路写的很清晰了,每个水站覆盖的干旱城市在有解情况下一定是一个区间,否则无解,然后剩下的就是线段覆盖问题啦。

求每个水站覆盖的区间:

用记忆化搜索,设l(i,j),r(i,j)分别表示从(i,j)可以到达的区间左端点和右端点,那么每次Flood fill时遇到已到达的位置就可以直接使用信息,不需要再次进行搜索,这样就将Flood fill的复杂度降到O(nm)。(记忆化使用深搜的话更加方便,实在不行就手写栈吧。。(没开O2的STL实在好慢。。。))

线段覆盖:实在不清楚DP的写法,所以我自己写了一个O(n log n)的贪心,现将线段按照左端点排序,然后设一个数组f(),初始时全为正无穷(除0),f(0)=0,然后扫描线段,每次取区间[l-1,m]中的最小值,设为Fmin,然后更新f(r)为min(f(r),Fmin+1),全部扫描完毕后f(m)即为答案。(用树状数组或线段树优化可以做到O(n log n),建议常数较小的BIT)

复杂度:flood fill O(nm) 线段覆盖O(m log m) 所以总复杂度O(nm+m log m)

速度勉勉强强(vijos):

a1ec08fa513d269786796c4d57fbb2fb4316d87c.jpg.png

代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
#define MAXN 510
#define lowbit(x)(((~(x))+1)&x)
#define inf 0x7fffffff
#define update(v) l[X[v]][Y[v]]=min(l[X[v]][Y[v]],l[X[v+1]][Y[v+1]]),r[X[v]][Y[v]]=max(r[X[v]][Y[v]],r[X[v+1]][Y[v+1]]);
 
bool f[MAXN][MAXN];
int n,m,h[MAXN][MAXN],ansv=0,ansm=0,l[MAXN][MAXN],r[MAXN][MAXN],X[MAXN*MAXN],Y[MAXN*MAXN],T[MAXN];
struct node{
        int x,y;
        node (int _x,int _y):x(_x),y(_y){
        }
};
queue<node>Q;
struct saver{
        int l,r;
} Seg[MAXN];
int Sn=0;
bool Cmp(saver x,saver y){return x.l<y.l;}
void dfs(int v){
        l[X[v]][Y[v]]=inf,r[X[v]][Y[v]]=-inf,f[X[v]][Y[v]]=false;
        if(X[v]==n) l[X[v]][Y[v]]=r[X[v]][Y[v]]=Y[v];
        if(X[v]-1&&h[X[v]-1][Y[v]]<h[X[v]][Y[v]]){
             X[v+1]=X[v]-1,Y[v+1]=Y[v];
               if(f[X[v]-1][Y[v]]) dfs(v+1);
               update(v);
        }
        if(X[v]+1<=n&&h[X[v]+1][Y[v]]<h[X[v]][Y[v]]){
                   X[v+1]=X[v]+1,Y[v+1]=Y[v];
               if(f[X[v]+1][Y[v]]) dfs(v+1);
               update(v);
        }
        if(Y[v]-1&&h[X[v]][Y[v]-1]<h[X[v]][Y[v]]){
             X[v+1]=X[v],Y[v+1]=Y[v]-1;
               if(f[X[v]][Y[v]-1]) dfs(v+1);
               update(v);
        }
        if(Y[v]+1<=m&&h[X[v]][Y[v]+1]<h[X[v]][Y[v]]){
             X[v+1]=X[v],Y[v+1]=Y[v]+1;
               if(f[X[v]][Y[v]+1]) dfs(v+1);
               update(v);
        }
}
int Min(int x){int rec=inf;for(int i=x;i;i-=lowbit(i)) rec=min(rec,T[i]);return rec;}
void Add(int x,int y){for(int i=x;i<=m+1;i+=lowbit(i)) T[i]=min(T[i],y);}
void getint(int&x){scanf("%d",&x);}
int main(){
        getint(n),getint(m);
        for(int i=0;i++<n;)for(int j=0;j++<m;)getint(h[i][j]);
        memset(f,true,sizeof(f));
        for(int i=0;i++<m;){
               while(!Q.empty()) Q.pop();
               Q.push(node(1,i));
               while(!Q.empty()){
                       node u=Q.front();
                       Q.pop();
                       if(!f[u.x][u.y])continue;
                       f[u.x][u.y]=false;
                       if(u.x-1&&h[u.x-1][u.y]<h[u.x][u.y]) Q.push(node(u.x-1,u.y));
                       if(u.x+1<=n&&h[u.x+1][u.y]<h[u.x][u.y]) Q.push(node(u.x+1,u.y));
                       if(u.y-1&&h[u.x][u.y-1]<h[u.x][u.y]) Q.push(node(u.x,u.y-1));
                       if(u.y+1<=m&&h[u.x][u.y+1]<h[u.x][u.y]) Q.push(node(u.x,u.y+1));
               }
        }
        for(int i=0;i++<m;)if(f[n][i]) ansv++;
        if(ansv){
               printf("0\n%d\n",ansv);
               return 0;
        }
        memset(f,true,sizeof(f));
        for(int i=0;i++<m;){
               X[1]=1,Y[1]=i;
               dfs(1);
               if(l[1][i]<inf&&r[1][i]>-inf){
                       Seg[Sn].l=l[1][i],Seg[Sn].r=r[1][i];
                       Sn++;
               }
        }
        for(int i=0;i++<m;) T[i]=inf;
        T[m+1]=0;
        sort(Seg,Seg+Sn,Cmp);
        for(int i=0;i<Sn;i++){
               Add(m-Seg[i].r+1,Min(m-Seg[i].l+2)+1);
        }
        printf("1\n%d\n",T[1]);
        return 0;
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容

  • mean to add the formatted="false" attribute?.[ 46% 47325/...
    ProZoom阅读 2,689评论 0 3
  • 这个不错分享给大家,从扣上看到的,就转过来了 《电脑专业英语》 file [fail] n. 文件;v. 保存文...
    麦子先生R阅读 6,545评论 5 24
  • 开篇.童子命(恐怖小说,正在赶稿,不定期在专题“煎蛋君的连载”更新) 准备写下这些东西的时候,自己犹豫了很久,因为...
    煎蛋君阅读 1,330评论 2 3
  • 从自以为旷世绝恋般情深意浓的爱情走入日见模糊的婚姻,不知道是对还是错。 今晚我们又吵架了。 一个女人到底该在婚姻里...
    934a934阅读 159评论 0 0