P2055 [ZJOI2009]假期的宿舍 - 二分图最大匹配

Posted zolrk

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P2055 [ZJOI2009]假期的宿舍 - 二分图最大匹配相关的知识,希望对你有一定的参考价值。

把人和床分开考虑,题目说每个人只能睡和自己直接认识的人的床,就是一种边的关系,但是并不是人与人,实际上人与人之间连边是很难处理的,但是如果把人和床连边,就是一张二分图,左右两边分别是不同的东西,然后求一下最大匹配就好了
没思路的时候换换角度,看能不能搞出什么“新东西”来
注意多组数据不超时的情况下能用memset尽量用,有时候感觉某个数组可以不清空但实际上是需要清空的
还有注意连边的时候没那么简单。。。看注释吧

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
#define debug(x) cerr << #x << "=" << x << endl;
const int MAXN = 210;

int n,m,match[MAXN],ans,edge_tot,tot,outnum,last[MAXN],vis[MAXN],gra[MAXN][MAXN],house[MAXN]; 
int sch[MAXN],t,bad[MAXN];

struct Edge{
    int u,v,to;
    Edge(){}
    Edge(int u, int v, int to) : u(u), v(v), to(to) {}
}e[10010];

inline void add(int u, int v) {
    e[++edge_tot] = Edge(u, v, last[u]);
    last[u] = edge_tot;
}

bool dfs(int x) {
    for(int i=last[x]; i; i=e[i].to) {
        int v = e[i].v;
        if(vis[v]) continue;
        vis[v] = 1;
        if(!match[v] || dfs(match[v])) {
            match[v] = x;
            return true;
        }
    }
    return false;
}

int main() {
    scanf("%d", &t);
    while(t--) {
        
        ans = 0, edge_tot = 0, outnum = 0;
        memset(match, 0, sizeof(match));
        memset(last, 0, sizeof(last));
        memset(house, 0, sizeof(house));
        memset(sch, 0, sizeof(sch));
        
        scanf("%d", &n);
        for(int i=1; i<=n; i++) {
            scanf("%d", &sch[i]);
        }
        for(int i=1; i<=n; i++) {
            int temp_sca = 0;
            if(sch[i] == 1) scanf("%d", &house[i]);
            else scanf("%d", &temp_sca), outnum++;
            if(!house[i] && sch[i]) {//和自己的床连边,首先i得有床,其次得不回家
                outnum++;
                add(i, i+n);
                add(i+n, i);
            }
        }
        for(int i=1; i<=n; i++) {
            for(int j=1; j<=n; j++) {
                scanf("%d", &gra[i][j]);
                if(gra[i][j] && sch[j] && house[i] == 0) {
                    add(i, j+n);//i这个人和j的床位连边,需要i不是回家的人并且j是有床的(j不一定必须回家)
                    add(j+n, i);
                }
            }
        }
        for(int i=1; i<=n; i++) {
            if(!house[i]) {
                memset(vis, 0, sizeof(vis));
                if(dfs(i)) ans++;
            }
        }
        if(ans == outnum) {
            printf("^_^
");
        } else printf("T_T
");
    }
    return 0;
} 

以上是关于P2055 [ZJOI2009]假期的宿舍 - 二分图最大匹配的主要内容,如果未能解决你的问题,请参考以下文章

P2055 [ZJOI2009]假期的宿舍(二分图&最大流)

P2055 [ZJOI2009]假期的宿舍

P2055 [ZJOI2009]假期的宿舍

P2055 [ZJOI2009]假期的宿舍

P2055 [ZJOI2009]假期的宿舍 - 二分图最大匹配

[ZJOI2009]假期的宿舍