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 }
  • 相关阅读:
    AngularJS $http模块POST请求
    thinkphp整合系列之融云即时通讯在线聊天
    Linux 常用命令
    Linux Shell脚本编写规范、例子
    Linux crontab定时执行任务 命令格式与详细例子
    Linux目录详细说明大全, 方便你以后合理规划及管理
    Linux 操作MySQL常用命令行
    SVN服务器搭建和使用(三)
    Linux下的SVN服务器搭建
    python 根据染色体起始终止点坐标来获取碱基序列
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/9857179.html
Copyright © 2011-2022 走看看