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("^_^\n");
        } else printf("T_T\n");
    }
    return 0;
} 

原文地址:https://www.cnblogs.com/Zolrk/p/9785128.html

时间: 2024-10-09 13:25:42

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

luogu P2055 [ZJOI2009]假期的宿舍

二次联通门 : luogu P2055 [ZJOI2009]假期的宿舍 /* luogu P2055 [ZJOI2009]假期的宿舍 建图时分为两个集合 床一个集合 人一个集合 S到床连边 人与自己认识的人连边 人与T点连边 然后跑最大流判断即可 */ #include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <queue> #de

[BZOJ1433][ZJOI2009]假期的宿舍 二分图匹配

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1433 首先留在学校的学生向自己的床连边. 要住在学校里的人向认识的学生的床连边. 跑二分图匹配,看匹配的数量是否等于住在学校的人数. 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 int inline readint(){ 6 int N

BZOJ1433 [ZJOI2009]假期的宿舍 二分图匹配 匈牙利算法

原文链接http://www.cnblogs.com/zhouzhendong/p/8372785.html 题目传送门 - BZOJ1433 题解 我们理一理题目. 在校的学生,有自己的床,还可以睡朋友的床. 离校的学生,不占床. 外来的学生,只能睡朋友的床. 然后就是一个裸的二分图匹配了. 代码 #include <cstring> #include <cstdlib> #include <cmath> #include <cstdio> #includ

P2055 [ZJOI2009]假期的宿舍

题目描述 学校放假了 · · · · · · 有些同学回家了,而有些同学则有以前的好朋友来探访,那么住宿就是一个问题.比如 A 和 B 都是学校的学生,A 要回家,而 C 来看B,C 与 A 不认识.我们假设每个人只能睡和自己直接认识的人的床.那么一个解决方案就是 B 睡 A 的床而 C 睡 B 的床.而实际情况可能非常复杂,有的人可能认识好多在校学生,在校学生之间也不一定都互相认识.我们已知一共有 n 个人,并且知道其中每个人是不是本校学生,也知道每个本校学生是否回家.问是否存在一个方案使得所

【最大流,dinic】P2055 [ZJOI2009]假期的宿舍

1 #include<iostream> 2 #include<queue> 3 #include<cstring> 4 using namespace std; 5 6 const int maxn = 60; 7 8 const int INF = 0x3f3f3f3f; 9 int n; 10 int head[maxn << 2 | 1]; 11 int cnt; 12 int d[maxn << 2 | 1]; 13 int now[m

bzoj1433:[ZJOI2009]假期的宿舍

明显的二分图最大匹配. #include<cstdio> #include<cstring> #include<cctype> #include<algorithm> #include<bitset> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c

[ZJOI2009]假期的宿舍

1433: [ZJOI2009]假期的宿舍 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2870  Solved: 1213[Submit][Status][Discuss] Description Input Output Sample Input 1 3 1 1 0 0 1 0 0 1 1 1 0 0 1 0 0 Sample Output ˆ ˆ HINT 对于30% 的数据满足1 ≤ n ≤ 12.对于100% 的数据满足1 ≤ n ≤

bzoj1433: [ZJOI2009]假期的宿舍

1433: [ZJOI2009]假期的宿舍 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2286  Solved: 969[Submit][Status][Discuss] Description Input Output Sample Input 131 1 00 1 00 1 11 0 01 0 0 Sample Output ˆ ˆ HINT 对于30% 的数据满足1 ≤ n ≤ 12.对于100% 的数据满足1 ≤ n ≤ 50,1 ≤

bzoj1433[ZJOI2009]假期的宿舍(匈牙利)

1433: [ZJOI2009]假期的宿舍 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2544  Solved: 1074 [Submit][Status][Discuss] Description Input Output Sample Input 1 3 1 1 0 0 1 0 0 1 1 1 0 0 1 0 0 Sample Output ˆ ˆ HINT 对于30% 的数据满足1 ≤ n ≤ 12.对于100% 的数据满足1 ≤ n