zoukankan      html  css  js  c++  java
  • 【UVALive

    题意:

      有n架飞机需要着陆。每架飞机有两种选择,早着陆或者晚着陆,二选其一。现在为了保证飞机的着陆安全,要求两架着陆的飞机的时间间隔的最小值达到最大。

    分析:

      最小值最大问题我们想到二分答案。对于猜测值x,判断是否有一种方案使相邻两着陆时间都不小于x。

      如果两架飞机的某着陆时间差小于p,证明不能同时选择。根据这个条件建图,再用2-SAT判断是否有解即可。

    代码如下:

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #define Maxn 2010
     5 #define Maxm 10000010
     6 
     7 int n;
     8 int first[2*Maxn],mark[2*Maxn],s[2*Maxn];
     9 int a[Maxn],b[Maxn];
    10 int c,v;
    11 
    12 struct node
    13 {
    14     int x,y,next;
    15 }t[4*Maxm];int len;
    16 
    17 int mymax(int x,int y) {return x>y?x:y;}
    18 int myabs(int x) {return x<0?-x:x;}
    19 
    20 void ins(int x,int y)
    21 {
    22     t[++len].x=x;t[len].y=y;
    23     t[len].next=first[x];first[x]=len;
    24 }
    25 
    26 bool dfs(int x)
    27 {
    28     if(mark[x^1]) return 0;
    29     if(mark[x]) return 1;
    30     mark[x]=1;
    31     s[++c]=x;
    32     for(int i=first[x];i;i=t[i].next)
    33      if(!dfs(t[i].y)) return 0;
    34     return 1;
    35 }
    36 
    37 bool solve()
    38 {
    39     memset(mark,0,sizeof(mark));
    40     for(int i=0;i<n;i++)
    41      if(!mark[2*i]&&!mark[2*i+1])
    42      {
    43          c=0;
    44          if(!dfs(2*i))
    45          {
    46              while(c>0) mark[s[c--]]=0;
    47              if(!dfs(2*i+1)) return 0;
    48         }
    49       }
    50       return 1;
    51 }
    52 
    53 bool check(int x)
    54 {
    55     memset(first,0,sizeof(first));len=0;
    56     for(int i=1;i<=n;i++)
    57      for(int j=i+1;j<=n;j++)
    58      {
    59         if(myabs(a[i]-a[j])<x)  {ins((i-1)*2,(j-1)*2+1);     ins((j-1)*2,(i-1)*2+1);}
    60          if(myabs(a[i]-b[j])<x) {ins((i-1)*2,(j-1)*2);     ins((j-1)*2+1,(i-1)*2+1);}
    61          if(myabs(b[i]-a[j])<x) {ins((i-1)*2+1,(j-1)*2+1);  ins((j-1)*2,(i-1)*2);}
    62          if(myabs(b[i]-b[j])<x) {ins((i-1)*2+1,(j-1)*2);      ins((j-1)*2+1,(i-1)*2);}
    63      }
    64     return solve();
    65 }
    66 
    67 void ffind(int l,int r)
    68 {
    69     int mid;
    70     while(l<r)
    71     {
    72         mid=(l+r+1)>>1;
    73         if(check(mid)) l=mid;
    74         else r=mid-1;
    75     }
    76     printf("%d
    ",l);
    77 }
    78 
    79 int main()
    80 {
    81     while(scanf("%d",&n)!=EOF)
    82     {
    83         int mx=0;
    84         for(int i=1;i<=n;i++)
    85         {
    86             scanf("%d%d",&a[i],&b[i]);
    87             mx=mymax(mx,mymax(a[i],b[i]));
    88         }
    89         ffind(0,mx);
    90     }
    91     return 0;
    92 }
    [LA3211]

    2016-03-25 13:46:05

  • 相关阅读:
    python之filter()函数
    figure margins too large错误解决
    “一个字等于多少个字节?”是一个不严谨的问法
    如何区分按字节编址与按字编址
    (stm32学习总结)—LCD—液晶显示
    (stm32学习总结)—GPIO位带操作
    (stm32学习总结)—SPI-FLASH 实验
    修改寄存器的位操作方法
    (stm32学习总结)—对寄存器的理解
    (stm32f103学习总结)—初识stm32
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/5319155.html
Copyright © 2011-2022 走看看