zoukankan      html  css  js  c++  java
  • 269D Maximum Waterfall

    传送门

    题目大意

    给出一些墙,水从高往低流,每次只能到达一面墙,选择一个路径,使得路径上的流量的最小值最大。

    分析

    这是一道经典的扫描线题,我们发现能够合法的线段对数至多只有n对。将一条线段拆成两个点,自左向右排序依次加入set中,按照高度关系将它们相连,详见代码(也可以用线段树做这道题,有时间再补吧qwq)。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    #define sp cout<<"---------------------------------------------------"<<endl
    const int inf=2e9+7;
    struct node {
          int h,x,wh,id;
    };
    bool operator < (node a,node b){
          if(a.x!=b.x)return a.x<b.x;
          if(a.wh!=b.wh)return a.wh<b.wh;
          return a.id<b.id;
    }
    vector<node>ev;
    set<pair<int,int> >s;
    vector<int>g[210000];
    vector<int>c[210000];
    int ans[210000],le[210000],ri[210000];
    inline int what(int x,int y){return (min(ri[x],ri[y])-max(le[x],le[y]));}
    inline int work(int x){
          if(ans[x]!=-1)return ans[x];
          if(x==1)return inf;
          int res=0;
          for(int i=0;i<(int)g[x].size();i++)
            res=max(res,min(c[x][i],work(g[x][i])));
          return ans[x]=res;
    }
    int main(){
          int n,m,i,H,L,R;
          scanf("%d%d",&n,&m);
          n+=2;
          le[0]=le[1]=-inf;
          ri[0]=ri[1]=inf;
          for(i=2;i<n;i++){
              scanf("%d%d%d",&H,&L,&R);
              le[i]=L;
              ri[i]=R;
            ev.push_back(node{H,L,1,i});
            ev.push_back(node{H,R,0,i});
          }
          sort(ev.begin(),ev.end());
          s.insert(make_pair(m,0));
          s.insert(make_pair(0,1));
          for(i=0;i<(int)ev.size();i++){
              if(ev[i].wh==0){
                s.erase(make_pair(ev[i].h,ev[i].id));
            }else {
              set<pair<int,int> >::iterator it=
              s.insert(make_pair(ev[i].h,ev[i].id)).first;
              int dw=(--it)->second;
              it++;
              int up=(++it)->second;
              if(g[up].size()&&g[up].back()==dw){
                  g[up].pop_back();
                  c[up].pop_back();
              }
              g[up].push_back(ev[i].id);
              c[up].push_back(what(ev[i].id,up));
              g[ev[i].id].push_back(dw);
              c[ev[i].id].push_back(what(ev[i].id,dw));
            }
          }
          memset(ans,-1,sizeof(ans));
          cout<<work(0)<<endl;
          return 0;
    }
  • 相关阅读:
    day24 Pyhton学习 反射
    正则表达式练习
    day23 Pyhton学习 昨日回顾.re模块.序列化模块
    day22 函数整理
    day22 Pyhton学习 re模块和正则表达式
    day21 Pyhton学习 模块
    函数整理
    一个关于浮点数运算需要注意的地方
    关于逻辑运算案例笔记
    数据的表现形式和进制之间的转换
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9341265.html
Copyright © 2011-2022 走看看