zoukankan      html  css  js  c++  java
  • HDU 2828 Lamp 二分图的最大匹配 模型题

    http://acm.hdu.edu.cn/showproblem.php?pid=2828

    给定n个灯,m个开关,使得每栈灯亮,前提是控制这栈灯的开关的状态是其中一个。(题目应该都看得懂)

    其实我想了挺久的,比赛的时候还想不出。但是直觉就告诉我是二分图匹配,虽然网上说什么精确覆盖。

    不懂。

    我的做法是:

    m个开关,则有2 * m种状态,以1号顶点表示1号灯是开得,1 + m号顶点表示1号灯是关的。

    那么,进行一次二分匹配,模板需要改一下,

    1、如果第i号灯需要第j个开关是ON的状态,但是第j个开关的ON的状态已经被人选了,那么,就可以默认第i号灯是true的了。

    2、如果你想选第j个开关是OFF的状态,那么就要询问下第j个开关的ON的状态是否被别人选了,如果是,就进行套路,就是找增广路。

    3、记得修改match[i],这里卡了我wa,不知道怎么说,看看代码吧。

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <assert.h>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    #include <bitset>
    int n, m;
    const int maxn = 500 * 2;
    struct Edge {
        int u, v, tonext;
    }e[maxn * 2];
    int num, first[maxn];
    void add(int u, int v) {
        ++num;
        e[num].u = u, e[num].v = v, e[num].tonext = first[u];
        first[u] = num;
    }
    bool book[maxn * 2];
    int match[maxn * 2];
    bool dfs(int u) {
        for (int i = first[u]; i; i = e[i].tonext) {
            int v = e[i].v;
            if (book[v] == false) {
                book[v] = true;
                if (v > m) book[v - m] = true;
                else book[v + m] = true;
                if (match[v]) return true;
                if (v > m) {
                    if (match[v - m] == 0 || dfs(match[v - m])) {
                        match[v - m] = 0;
                        match[v] = u;
                        return true;
                    }
                } else {
                    if (match[v + m] == 0 || dfs(match[v + m])) {
                        match[v + m] = 0; //dfs那里的要清空
                        match[v] = u;
                        return true;
                    }
                }
            }
        }
        return false;
    }
    int hungary() {
        int ans = 0;
        for (int i = 1; i <= n; ++i) {
            memset(book, false, sizeof book);
            if (dfs(i)) ans++;
        }
        return ans;
    }
    void init() {
        memset(first, 0, sizeof first);
        memset(match, 0, sizeof match);
        num = 0;
    }
    void work() {
        init();
        for (int i = 1; i <= n; ++i) {
            int k;
            scanf("%d", &k);
            while (k--) {
                int id;
                char op[22];
                scanf("%d%s", &id, op);
                if (op[1] == 'N') {
                    add(i, id);
                } else {
                    add(i, id + m);
                }
            }
        }
        int res = hungary();
        if (res != n) {
            cout << "-1" << endl;
            return;
        }
    //    for (int i = 1; i <= n; ++i) {
    //        cout << match[i] << " ";
    //    }
    //    cout << endl;
        for (int i = 1; i <= m - 1; ++i) {
            if (match[i]) {
                printf("ON ");
            } else {
                printf("OFF ");
            }
        }
        if (match[m]) {
            printf("ON");
        } else printf("OFF");
        printf("
    ");
    }
    
    int main() {
    #ifdef local
        freopen("data.txt", "r", stdin);
    //    freopen("data.txt", "w", stdout);
    #endif
        while (scanf("%d%d", &n, &m) != EOF) work();
        return 0;
    }
    View Code
  • 相关阅读:
    路由器只要能连接上,就能得到密码,
    jmeter上传文件搞了一天,才搞定,没高人帮忙效率就是低,赶紧记下来,以备后用
    1关0不关
    AJAX学习
    建表原则
    设计模式——代理模式
    jdk动态代理机制
    ArrayList源码分析
    Java集合类:HashMap (基于JDK1.8)
    SpringMVC的数据转换、格式化和数据校验
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/6517820.html
Copyright © 2011-2022 走看看