[ZJOI 2009] 假期的宿舍

[题目链接]

         https://www.lydsy.com/JudgeOnline/problem.php?id=1433

[算法]

         二分图匹配
[代码]

        

#include<bits/stdc++.h>
using namespace std;
#define MAXN 55

struct edge
{
        int to,nxt; 
} e[MAXN * MAXN];

int i,j,n,T,tot;
int a[MAXN],b[MAXN],head[MAXN],match[MAXN << 1];
bool visited[MAXN << 1];
bool g[MAXN][MAXN];
bool ans;

template <typename T> inline void read(T &x)
{
        int f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar()) 
        {
                if (c == '-') f = -f;
        }
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        x *= f;
}
inline void addedge(int u,int v)
{
        tot++;
        e[tot] = (edge){v,head[u]};
        head[u] = tot;
}
inline bool hungary(int u)
{
        int i,v;
        visited[u] = true;
        for (i = head[u]; i; i = e[i].nxt)
        {
                v = e[i].to;
                if (!visited[v])
                {
                        visited[v] = true;
                        if (!match[v] || hungary(match[v]))
                        {
                                match[v] = u;
                                return true;
                        }
                }
        }
        return false;
}

int main() 
{
        
        read(T);
        while (T--)
        {
                read(n);
                tot = 0;
                for (i = 1; i <= n; i++) 
                {
                        head[i] = 0;
                        match[i] = match[n + i] = 0;
                }
                for (i = 1; i <= n; i++) read(a[i]);
                for (i = 1; i <= n; i++) read(b[i]);
                for (i = 1; i <= n; i++)
                {
                        for (j = 1; j <= n; j++)
                        {
                                read(g[i][j]);        
                        }        
                }        
                for (i = 1; i <= n; i++)
                {
                        if (a[i] == 1)
                        {
                                if (b[i] == 1) continue;
                                for (j = 1; j <= n; j++)
                                {
                                        if ((i == j) || (a[j] == 1 && g[i][j]))
                                                addedge(i,j + n);    
                                }    
                        }    else
                        {
                                for (j = 1; j <= n; j++)
                                {
                                        if (a[j] == 1 && g[i][j])
                                                addedge(i,j + n);
                                }
                        }
                }        
                ans = true;
                for (i = 1; i <= n; i++)
                {
                        if ((a[i] == 1 && b[i] == 0) || a[i] == 0) 
                        {
                                memset(visited,false,sizeof(visited));
                                if (!hungary(i))
                                {
                                        ans = false;
                                        break;
                                }
                        }
                }
                if (ans) printf("^_^\n");
                else printf("T_T\n");
        } 
        
        return 0;
    
}

 

posted @ 2018-08-17 13:14  evenbao  阅读(191)  评论(0编辑  收藏  举报