算法:UVa 1146

【题目大意】

有n架飞机要着陆, 每架飞机都可以选择“早着陆”或者“晚着陆”中的一种,不 能在其他时间着陆。 给出每架飞机“早着陆”和“玩着陆”的时间, 问怎样安排着陆,才可以使得着任意 两架飞机的陆时间间隔最小,输出最小值。

【思路】

水题,二分最小间隔时间,用2-SAT判 断。

【代码】

#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;  

const int MAXN = 2005;
const int VN   = MAXN*2;
const int EN   = MAXN*MAXN*4;
int n, m;
int t[MAXN][2];  

struct Graph{
    int size, head[VN];
    struct{int v, next; }E[EN];
    void init(){size=0; memset(head, -1, sizeof(head));}
    void addEdge(int u, int v){
        E[size].v = v;
        E[size].next = head[u];
        head[u] = size++;
    }
}g;  

class Two_Sat{
public:
    bool check(){
        scc();
        for(int i=0; i<n; ++i)
            if(belong[i] == belong[i+n])
                return false;
        return true;
    }
private:
    void tarjan(const int u){
        int v;
        low[u] = dfn[u] = ++idx;
        instack[u] = true;
        sta[top++] = u;
        for(int e=g.head[u]; e!=-1; e=g.E[e].next){
            v = g.E[e].v;
            if(dfn[v] == -1){
                tarjan(v);
                low[u] = min(low[u], low[v]);
            }else if(instack[v])
                low[u] = min(low[u], dfn[v]);
        }
        if(dfn[u] == low[u]){
            ++bcnt;
            do{
                v = sta[--top];
                instack[v] = false;
                belong[v] = bcnt;
            }while(u != v);
        }
    }
    void scc(){
        idx = top = bcnt = 0;
        memset(instack, 0, sizeof(instack));
        memset(dfn, -1, sizeof(dfn));
        for(int i=0; i<2*n; ++i)
            if(dfn[i] == -1)
                tarjan(i);
    }
private:
    int idx, top, bcnt;
    int sta[VN], low[VN], dfn[VN], belong[VN];
    bool instack[VN];
}sat;  

void buildGraph(int minT){
    g.init();
    for(int i=0; i<n; ++i){
        for(int j=i+1; j<n; ++j){
            int ta1=t[i][0], ta2=t[i][1];
            int tb1=t[j][0], tb2=t[j][1];  

            if(abs(ta1-tb1) < minT){
                g.addEdge(i, j+n);
                g.addEdge(j, i+n);
            }
            if(abs(ta1-tb2) < minT){
                g.addEdge(i, j);
                g.addEdge(j+n, i+n);
            }
            if(abs(ta2-tb1) < minT){
                g.addEdge(i+n, j+n);
                g.addEdge(j, i);
            }
            if(abs(ta2-tb2) < minT){
                g.addEdge(i+n, j);
                g.addEdge(j+n, i);
            }
        }
    }
}  

int main(){  

    while(~scanf("%d", &n)){  

        for(int i=0; i<n; ++i)
            scanf("%d%d", &t[i][0], &t[i][1]);  

        int l=0, r=1e7, mid, ans=-1;
        while(l < r){
            mid = (l+r)>>1;
            buildGraph(mid);
            if(sat.check()){
                ans = mid;
                l = mid+1;
            }else
                r = mid;
        }
        printf("%d\n", ans);
    }
    return 0;
}

查看本栏目更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/sjjg/

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索int
, include
, 时间
, head
, size
, 最小
1146
mysql 1146、mysql 1146错误、qt1146、1146年、1147,以便于您获取更多的相关知识。

时间: 2024-08-24 12:23:35

算法:UVa 1146的相关文章

算法题之UVA 763

Fibinary Numbers The standard interpretation of the binary number 1010 is 8 + 2 = 10. An alternate way to view the sequence ``1010'' is to use Fibonacci numbers as bases instead of powers of two. For this problem, the terms of the Fibonacci sequence

算法题:UVa 591 Box of Bricks (模拟)

591 - Box of Bricks Time limit: 3.000 seconds http://uva.onlinejudge.org/index.php? option=com_onlinejudge&Itemid=8&category=467&page=show_problem&problem=53 2 Little Bob likes playing with his box of bricks. He puts the bricks one upon an

算法题之UVA 10891

This is a two player game. Initially there are n integer numbers in an array and players A and B get chance to take them alternatively. Each player can take one or more numbers from the left or right end of the array but cannot take from both ends at

算法题:uva 10318

题目链接: 首先,可以确定每个格子只能选一次,因为选任何大于0的偶数次,等于没有效果 一样. 然后,就可以把这题理解成从r*c的矩阵中选择一些格子进行"点亮"操作,使得最终所 有格子都是"亮"的状态.那么,每个格子要么有点亮操作,要么没有,总共复杂度为2^25,显然必须 进行减枝. 假设从第一行第一列开始,从左往右,从上往下一次依次选择,对于当前所在位置( x, y),它已经不能影响到x-2以前的行数了,所以当到x行时,如果第x-2行没有全部点亮,则进行减枝 . 此

算法题:uva 1330

题目链接: http://uva.onlinejudge.org/index.php? option=com_onlinejudge&Itemid=8&category=460&page=show_problem&problem=4076 以前做过一道一维的,这题只是变成了二维的,其他方法都一样.HDU 1506  Largest Rectangle in a Histogram   题解 代码1: #include<cstdio> #include<cs

算法:UVa 11572

题目大意: 给n个数, n<=100W,求一个连续子序列,这个子序列中没有重复的数,问这个子序列最长是多少? 思路: 开一个数组pos,  pos[ x ] 表示x出现的位置, 这个数组初始化为-1 用一个变量start来记录当前枚举序列的起点,初始为0 然后枚举这个序列,依次记录每个数的位置, 假设当前枚举到i, 在记录这个位置之前,先检查当前这个数的位置pos[ arr[i] ]是否大于等于start,如果大于,说明这个数已经在[start, i-1]中已经出现过了,记下这个满足条件的子序列

算法:UVa 11536

题目大意: 给一个序列 X1 = 1 X2 = 2 X3 = 3 Xi = (Xi-1 + Xi-2 + Xi-3) % M + 1         for i = 4 to N 求一段最短的连续子序 列,使得这个子序列包含正整数[1,k] 思路: 扫描一遍即可,用一个队列记录下[1, k]区间内的数的位置,再用一个变量count维护[1,k]内不重复数的个数.当count等于k时说明当前 序列已经满足了要求,而队列头的数的位置就是起始位置. 算法复杂度O(n) 代码: /* * UVa 115

算法:UVa 12174

[题目大意] 你在听音乐播放器,它采用随机播放形式.随机播放的原理时先随机产生一个 1~n的排列,然后就按这个排列顺序播放歌曲.播放完这序列的所有歌曲以后,再次随机生成一个1-n的 排列,再继续播放. 现在给你一个播放历史记录,这个历史记录是不完整的,以为它是开始记录 时,已经有些歌曲播放过了而没有记录到. 现在给你一段从某个时刻开始的播放音乐的历史记录 ,以及播放器里一共有多少首歌. 问历史记录中第一首歌可能是某个随机列表中的第几首,总共 有多少种可能? [思路] 先进行预处理,用一个bool

UVa 10182 Bee Maja:规律&amp;amp;O(1)算法

10182 - Bee Maja Time limit: 3.000 seconds http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=1123 Maja is a bee. She lives in a bee hive with thousands of other bees. This bee hive c