`
king_tt
  • 浏览: 2290586 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

POJ 2723 Get Luffy Out(2-SAT + 二分)

 
阅读更多

【题目链接】

http://poj.org/problem?id=2723


【题目大意】

有2*N把不同的锁,每把锁有一个钥匙,所以共有2*N 把钥匙。把2*N把钥匙两两配对共分为N组。

有个M层楼,每层楼有一个门,每个门上有两把锁,可能是相同的也可能是不同的。 走上某层楼之前,必须要打开这个门上的至少一个锁。

要你从每组钥匙中选择一把钥匙,然后用这些钥匙去上这栋楼,问最多能走到几层楼?


【思路】

对于每组钥匙,只能二取一,所以是2-SAT模型。

问题是怎样找矛盾对并加边呢?

对于一个门上的两把锁,如果这两把锁的钥匙是同一组的,那么任选一个钥匙都可以。

如果是属于不同组的,那么假设这两把钥匙是a1, b1,那么这两组分别是(a1, a2) (b1, b2), a2和b2是一定不能同时选的,因为选了就没有a1或b1来打开这个门了

所以<a2,b2>是一个矛盾对,加入边a1->b2, b2->a1


然后题目是要求最多能打开多少个门, 那么二分一下最大数量打开门就可以了。



【代码】

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

const int MAXN = 2100;
const int VN   = MAXN*2;
const int EN   = VN;
int n, m;

struct Edge{
    int v, next;
};

struct Graph{
    int size, head[VN];
    Edge 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(const Graph& g, const int n){
        scc(g, 2*n);
        for(int i=0; i<2*n; i+=2)
            if(belong[i] == belong[i^1])
                return false;
        return true;
    }

private:
    void tarjan(const Graph& g, const int u){
        int v;
        DFN[u] = low[u] = ++idx;
        sta[top++] = u;
        instack[u] = true;

        for(int e=g.head[u]; e!=-1; e=g.E[e].next){
            v = g.E[e].v;
            if(DFN[v] == -1){
                tarjan(g, v);
                low[u] = min(low[u], low[v]);
            }else if(instack[v]){
                low[u] = min(low[u], DFN[v]); 
            }
        }

        if(low[u] == DFN[u]){
            ++bcnt;
            do{
                v = sta[--top];
                instack[v] = false;
                belong[v] = bcnt;
            }while(u != v);
        }
    }
    void scc(const Graph& g, const int n){
        idx = bcnt = top = 0;
        memset(DFN, -1, sizeof(DFN));
        memset(instack, 0, sizeof(instack));
        for(int i=0; i<n; ++i)
            if(DFN[i] == -1) 
                tarjan(g, i);
    }

private:
    int idx, top, bcnt;
    int DFN[VN];
    int low[VN];
    int belong[VN];
    int sta[VN];
    bool instack[VN];
}sat;

int key[VN];
int door[MAXN][2];
int idx[VN];


int main(){
    
    while(~scanf("%d%d", &n, &m) && n+m){
        
        for(int i=0; i<2*n; ++i){
            scanf("%d", &key[i]);
            idx[key[i]] = i;
        }
        for(int i=0; i<m; ++i)
            scanf("%d%d", &door[i][0], &door[i][1]);

        int l=0, r=m+1, mid;
        int ans = 0;
        while(l < r){
            mid = (l+r)>>1;
            // 建图
            g.init();
            for(int i=0; i<mid; ++i){
                int a1=door[i][0], b1=door[i][1];
                int a2=key[idx[a1]^1], b2=key[idx[b1]^1];
                if(a2 == b1) continue;
                if(a1==b1) g.addEdge(idx[b1], idx[b1]^1);
                else{
                    g.addEdge(idx[a1], idx[b1]^1);
                    g.addEdge(idx[b1], idx[a1]^1);
                }
            }

            if(sat.check(g, n)){
                ans = mid;
                l=mid+1;
            }
            else r=mid;
        }
        printf("%d\n", ans);
    }


    return 0;
}


分享到:
评论

相关推荐

    POJ水题集--50道--增加自信

    POJ水题集-----50道左右-----增加自信啊..

    ACM------搜索+(从入门到精通)

    非常详细的ACM 搜索类型题 配套POJ练习,有详细思路

    pku(poj)--2494--Acid Text--java代码

    根据给定的文件信息,我们可以总结出以下关于POJ(PKU)问题2494“Acid Text”以及其Java代码实现的关键知识点: ### 1. POJ(PKU)2494:Acid Text POJ(Peking University Online Judge)是北京大学的一个在线...

    POJ2002-Squares

    2. "POJ2002-Squares.doc":这可能是一个Microsoft Word文档,包含了详细的解题报告,可能包括问题分析、算法描述、解题步骤、运行结果和可能的优化措施等。 详细说明: 在"POJ2002-Squares"这个问题中,参赛者可能...

    POJ3253-POJ3253-Fence Repair【STL优先队列】

    2. "POJ3253-POJ3253-Fence Repair【STL优先队列】.cpp":这是使用STL中的优先队列数据结构来解决题目的代码。 3. "POJ3253-POJ3253-Fence Repair【朴素思想TLE】.cpp":这个文件可能包含了没有利用优先队列,而是...

    POJ1002-487-3279【Hash+Qsort】

    2. "POJ1002-487-3279【Qsort】.cpp":这个可能是单独实现快速排序部分的代码,可能用于比较不同的排序方法或作为哈希+快速排序方案的一部分。 3. "POJ1002-487-3279.doc":这是一个文档文件,很可能包含了详细的...

    poj多道----acm----解题报告

    在二维平面上,这可以通过链表或数组来实现,将每个顶点作为链表或数组的一个节点,并保证首尾相连。 3. **判断点灯位置**:检查灯的位置是否在多边形内部。这可以通过射线交叉法实现,即从灯的位置向任意方向发射...

    poj 1000 - 2000 部分题目 官方分类

    《POJ 1000 - 2000 部分题目 官方分类》 编程竞赛,特别是在线判题系统(如POJ,即Problem Online Judge)中的题目,是提升编程技能和算法理解的重要途径。POJ 1000 - 2000 是一个涵盖广泛的题目区间,包含了大量的...

    POJ3009-Curling 2.0【DFS+Vector+回溯+剪枝】

    《POJ3009-Curling 2.0:深度优先搜索、向量、回溯与剪枝的综合应用》 北京大学在线编程平台上的POJ3009题目名为"Curling 2.0",它是一道涉及到算法与数据结构的复杂问题,主要考察了参赛者对深度优先搜索(DFS)、...

    POJ 1002 487-3279 测试数据 完整

    East Central North America 1999。50字50字50字50字50字50字50字50字50字50字50字50字50字50字50字50字50字50字50字50字50字50字50字50字50字50字50字50字50字50字50字50字50字50字50字50字50字50字50字50字50字50...

    POJ 分类题目

    二分查找适用于有序数组。 - **示例题目**: - poj3349 - poj3274 - poj2151 - poj1840 - poj2002 - poj2503 - **应用场景**:适用于快速查找、统计频率等问题。 **5. 哈夫曼树** - **定义**:一种带权路径...

    poj2814.rar_5-101_adg_limit_poj 28_poj2814

    2 ABC 3 BCEF 4 ADG 5 BDEFH 6 CFI 7 DEGH 8 GHI 9 EFHI (图 2) 输入 从标准输入设备读入9个整数,表示各时钟指针的起始位置。1=12点、1=3点、2=6点、3=9点。 输出 输出一个最短的移动序列,使得9个时钟的指针都...

    POJ3292-Semi-prime H-numbers

    【标题】"POJ3292-Semi-prime H-numbers"是一个编程竞赛题目,源自北京大学的在线判题系统POJ(Problem Set of Peking University)。这个题目主要涉及数论和算法设计,特别是关于半素数(Semi-prime)的概念以及H-...

    POJ3733-Changing Digits【DFS+强剪枝】

    【标题】"POJ3733-Changing Digits【DFS+强剪枝】"是一个来自北京大学在线评测系统POJ的编程题目,该题目主要涉及深度优先搜索(DFS)算法和强剪枝策略。在算法竞赛和编程挑战中,这类问题通常要求参赛者通过编写...

    POJ1207-The 3n + 1 problem

    此外,对于大型数据,还可以考虑使用更高效的数据结构和算法优化,例如二分查找、位运算等。然而,对于POJ1207的规模,上述的简单动态规划方法已经足够高效。 总的来说,解答《POJ1207-The 3n + 1 problem》不仅...

    poj训练计划.doc

    根据给定的文件信息,我们可以总结出一份详细的IT知识训练计划,主要针对编程竞赛和算法学习,特别是聚焦于POJ(Problem Online Judge)平台上的题目训练。这份计划分为两个阶段,初级阶段和中级阶段,共计涉及了165...

    POJ3026-Borg Maze【BFS+Prim】

    《POJ3026-Borg Maze:BFS与Prim算法的应用解析》 在计算机科学领域,图论是解决问题的重要工具之一,而BFS(广度优先搜索)和Prim算法则是其中的两种经典算法。本篇文章将围绕北大POJ3026题目“Borg Maze”来探讨...

    poj图论题目汇总

    #### 2723 Get Luffy Out - 2-SAT - **知识点**:2-SAT问题,一种特殊的布尔满足性问题。 #### 2724 Purifying Machine - 二分匹配 - **知识点**:二分匹配算法。 #### 2728 Desert King - 最优比例生成树 - **...

    POJ3373-Changing Digits【DFS+强剪枝】

    标题“POJ3373-Changing Digits【DFS+强剪枝】”涉及的是一个编程竞赛中的问题,这个问题在北大POJ(北京大学在线评测系统)平台上被提出。"Changing Digits"是一个算法挑战,而解决方案是通过深度优先搜索(DFS)...

    POJ2186-Popular Cows【Tarjan+极大强连通分量+缩点】

    POJ2186-Popular Cows 【Tarjan+极大强连通分量+缩点】 解题报告+AC代码 http://hi.csdn.net/!s/BGDH68 附:我所有的POJ解题报告链接 . http://blog.csdn.net/lyy289065406/article/details/6642573

Global site tag (gtag.js) - Google Analytics