zoukankan      html  css  js  c++  java
  • codeforces 1027F. Session in BSU

    Polycarp studies in Berland State University. Soon he will have to take his exam. He has to pass exactly nn exams.

    For the each exam ii there are known two days: aiai — day of the first opportunity to pass the exam, bibi — day of the second opportunity to pass the exam (ai<biai<bi). Polycarp can pass at most one exam during each day. For each exam Polycarp chooses by himself which day he will pass this exam. He has to pass all the nn exams.

    Polycarp wants to pass all the exams as soon as possible. Print the minimum index of day by which Polycarp can pass all the nn exams, or print -1 if he cannot pass all the exams at all.

    Input

    The first line of the input contains one integer nn (1n1061≤n≤106) — the number of exams.

    The next nn lines contain two integers each: aiai and bibi (1ai<bi1091≤ai<bi≤109), where aiai is the number of day of the first passing the ii-th exam and bibi is the number of day of the second passing the ii-th exam.

    Output

    If Polycarp cannot pass all the nn exams, print -1. Otherwise print the minimum index of day by which Polycarp can do that.

    大意:

    一个人可以在 ai 和 bi 两个时间完成时间i,给定 n 个事件,询问是否可以完成。

    解题思路:

    图论构造好题。

    方案要匹配,总是要替换的。

    一个方案被占用,很大程度上是需要方案的替换的

    注意到这一点,假设一个方案 i 的替换方案为 j ,当方案 k 进入考虑时,若与 i 冲突,看看是替换好,还是自己退步好。

    选择劣质的状态作为新的替换方案。

    假设一个时间 i 为一个点,那么可以动态构建这样的树形结构:在 i 时间被占用后,而想要将 i 方案退化。那么这时将 i 的父亲指向其替换方案。

    我们可以发现,此时的退化方案就是 i 退化或者另一端退化,这样树就堆叠合并到了一起。

    换句话说,当一个时间指向自己的劣化方案,那么这样顺着找下去就是最终的让步方案了。

    我可能说的不好,那就来几张图:

    红色点代表可以被选的时间,白点代表已经被选的时间,那么初始状态就是上图。

    现在a1=1,b1=3更新,那么就是:

    若a2=1,b2=4更新,显然此时最优方案就是总时间为3,更新时1被占用,寻找劣化方案。

    我们可以证明,这样合并树会导致最终每棵树只有点可用

    所以就是并查集喽。

    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 class Auto_disperse{
      5     private:
      6         struct int_2{
      7             int val;
      8             int rnk;
      9             int no;
     10             bool friend operator < (int_2 x,int_2 y){return x.val<y.val;}
     11         };
     12         struct Ruye{
     13             int_2 line[10000000];
     14             int top;
     15             void sort(void){std::sort(line,line+top);return ;}
     16             void push_back(int_2 x){line[top++]=x;return ;}
     17             int size(void){return top;}
     18             void clear(void){top=0;return ;}
     19         }tmp;
     20         int cnt;
     21     public:
     22         void disp(int *a,int &len,int *ans)
     23         {
     24             tmp.clear();
     25             cnt=0;
     26             for(int i=1;i<=len;i++)
     27                 tmp.push_back((int_2){a[i],0,i});
     28             tmp.sort();
     29             cnt=1;
     30             tmp.line[0].rnk=1;
     31             for(int i=1;i<tmp.size();i++)
     32             {
     33                 if(tmp.line[i].val!=tmp.line[i-1].val)
     34                     cnt++;
     35                 tmp.line[i].rnk=cnt;
     36             }
     37             cnt=1;
     38             a[1]=tmp.line[0].val;
     39             ans[1]=tmp.line[0].rnk;
     40             for(int i=1;i<tmp.size();i++)
     41             {
     42                 if(tmp.line[i].val==tmp.line[i-1].val)
     43                     continue;
     44                 cnt++;
     45                 a[cnt]=tmp.line[i].val;
     46                 ans[cnt]=tmp.line[i].rnk;
     47             }
     48             len=cnt;
     49             return ;
     50         }
     51         int query(int *a,int *ans,int len,int san)
     52         {
     53             int l=1,r=len;
     54             while(l<=r)
     55             {
     56                 int mid=(l+r)>>1;
     57                 if(a[mid]==san)
     58                     return ans[mid];
     59                 if(a[mid]<san)
     60                     l=mid+1;
     61                 else
     62                     r=mid-1;
     63             }
     64             return ans[l];
     65         }
     66 }Dac;
     67 int fa[4000001];
     68 int n;
     69 int tot;
     70 int tmp[5000000];
     71 int val[5000000];
     72 int a[4000000];
     73 int b[4000000];
     74 int finf(int x)
     75 {
     76     if(!x)
     77         return 0;
     78     return x==fa[x]?x:fa[x]=finf(fa[x]);
     79 }
     80 void debug(int cmd)
     81 {
     82     if(cmd==1)
     83     {
     84         puts("Dac works:");
     85         for(int i=1;i<=tot;i++)
     86             printf("%d ",tmp[i]);
     87         puts("");
     88         for(int i=1;i<=tot;i++)
     89             printf("%d ",val[i]);
     90         puts("");
     91         return ;
     92     }
     93     if(cmd==2)
     94     {
     95         puts("a and b val:");
     96         for(int i=1;i<=n;i++)
     97             printf("%d ",a[i]);
     98         puts("");
     99         for(int i=1;i<=n;i++)
    100             printf("%d ",b[i]);
    101         puts("");
    102         return ;
    103     }
    104 }
    105 int exam(void)
    106 {
    107     int ans=-1;
    108     for(int i=1;i<=n;i++)
    109     {
    110         int fx=finf(a[i]);
    111         int fy=finf(b[i]);
    112         if(fx>=fy)
    113             std::swap(fx,fy);
    114         if(fx==0)
    115         {
    116             if(fy==0)
    117                 return -1;
    118             fa[fy]=0;
    119             ans=std::max(ans,fy);
    120         }
    121         fa[fx]=fy;
    122         if(fx==fy)
    123             fa[fx]=0;
    124         ans=std::max(fx,ans);
    125     }
    126     return Dac.query(val,tmp,tot,ans);
    127 }
    128 int main()
    129 {
    130 //    printf("%d
    ",(sizeof(Dac)+sizeof(fa)+sizeof(tmp)+sizeof(val)+sizeof(a)+sizeof(b))/1024/1024);
    131     scanf("%d",&n);
    132     for(int i=1;i<=n;i++)
    133     {
    134         scanf("%d%d",&a[i],&b[i]);
    135         tmp[++tot]=a[i];
    136         tmp[++tot]=b[i];
    137     }
    138 //    debug(1);
    139     Dac.disp(tmp,tot,val);
    140     for(int i=1;i<=tot;i++)
    141         fa[i]=i;
    142 //    debug(1);
    143 //    debug(2);
    144     for(int i=1;i<=n;i++)
    145     {
    146         a[i]=Dac.query(tmp,val,tot,a[i]);
    147         b[i]=Dac.query(tmp,val,tot,b[i]);
    148     }
    149 //    debug(2);
    150     printf("%d
    ",exam());
    151     return 0;
    152 }
  • 相关阅读:
    Linux Shell脚本启动jar、关闭jar
    SpringBoot基于切面来拦截@PathVariable参数及抛出异常全局处理方法
    SpringBoot引用font awesome不显示问题的解决
    解决RestTemplate请求url出现301转发错误 301 Moved Permanently
    npm报错:Node Sass could not find a binding for your current environment: Windows 64-bit with Node.js 10.x
    npm 安装 chromedriver 失败的解决办法
    npm run dev报错 JS stacktrace(Node内存溢出)
    Mysql批量修改表字段名称为小写
    Ubuntu18 apt更换国内源 加快下载速度
    微信小程序如何实现支付宝支付?
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/9857179.html
Copyright © 2011-2022 走看看