zoukankan      html  css  js  c++  java
  • uvalive 3211 Now or later

    算法指南

    就是从飞机早着陆还晚着路两种状态可以组合成一个点,类似2--sat把一个点划分成两个点来表示状态,再二分时间,如果小于时间则可以转化成相应的约数条件:“xi或xj为假”这样的条件。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<queue>
     5 #include<stack>
     6 #include<bits/stdc++.h>
     7 using namespace std;
     8 #define LL long long
     9 const int maxn = 2000 + 10;
    10 //模板
    11 struct TwoSAT {
    12     int n;
    13     vector<int> G[maxn*2];
    14     bool mark[maxn*2];
    15     int S[maxn*2], c;
    16 
    17     bool dfs(int x) {
    18         if (mark[x^1]) return false;
    19         if (mark[x]) return true;
    20         mark[x] = true;
    21         S[c++] = x;
    22         for (int i = 0; i <(int)G[x].size(); i++)
    23             if (!dfs(G[x][i])) return false;
    24         return true;
    25     }
    26 
    27     void init(int n) {
    28         this->n = n;
    29         for (int i = 0; i < n*2; i++) G[i].clear();
    30         memset(mark, 0, sizeof(mark));
    31     }
    32 
    33     // x = xval or y = yval
    34     void add_clause(int x, int xval, int y, int yval) {
    35         x = x * 2 + xval;
    36         y = y * 2 + yval;
    37         G[x^1].push_back(y);
    38         G[y^1].push_back(x);
    39     }
    40 
    41     bool solve() {
    42         for(int i = 0; i < n*2; i += 2)
    43             if(!mark[i] && !mark[i+1]) {
    44                 c = 0;
    45                 if(!dfs(i)) {
    46                     while(c > 0) mark[S[--c]] = false;
    47                     if(!dfs(i+1)) return false;
    48                 }
    49             }
    50         return true;
    51     }
    52 };
    53 
    54 TwoSAT solver;
    55 
    56 int n, T[maxn][2];
    57 
    58 bool test(int diff) {
    59     solver.init(n);
    60     for(int i = 0; i < n; i++) for(int a = 0; a < 2; a++)
    61             for(int j = i+1; j < n; j++) for(int b = 0; b < 2; b++)
    62                     if(abs(T[i][a] - T[j][b]) < diff) //只有小于diff的时候才满足布尔关系,详见算法指南
    63                     solver.add_clause(i, a^1, j, b^1);//i,j之间建立边,注意早飞还是晚飞状态
    64     return solver.solve();
    65 }
    66 
    67 int main() {
    68     while(scanf("%d", &n) == 1 && n) {
    69         int L = 0, R = 0;
    70         for(int i = 0; i < n; i++) for(int a = 0; a < 2; a++) {
    71                 scanf("%d", &T[i][a]);
    72                 R = max(R, T[i][a]);
    73             }
    74             //二分时间,如果大于中间值,则证明还可以增大时间
    75         while(L < R) {
    76             int M = L + (R-L+1)/2;
    77             if(test(M)) L = M;
    78             else R = M-1;
    79         }
    80         printf("%d
    ", L);
    81     }
    82     return 0;
    83 }
    View Code
  • 相关阅读:
    Good Bye 2014 B. New Year Permutation(floyd )
    hdu 5147 Sequence II (树状数组 求逆序数)
    POJ 1696 Space Ant (极角排序)
    POJ 2398 Toy Storage (叉积判断点和线段的关系)
    hdu 2897 邂逅明下 (简单巴什博弈)
    poj 1410 Intersection (判断线段与矩形相交 判线段相交)
    HDU 3400 Line belt (三分嵌套)
    Codeforces Round #279 (Div. 2) C. Hacking Cypher (大数取余)
    Codeforces Round #179 (Div. 2) B. Yaroslav and Two Strings (容斥原理)
    hdu 1576 A/B (求逆元)
  • 原文地址:https://www.cnblogs.com/ITUPC/p/5380668.html
Copyright © 2011-2022 走看看