[洛谷P2055]假期的宿舍

题目←

存一波匈牙利板子
check数组还是老老实实for一遍更新吧,回溯的时候更新容易出事

//:-)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define LL long long
using namespace std;
const int MAXN = 1000 + 50;
int n,c,x;
bool zx[MAXN],hj[MAXN];
bool need[MAXN];
struct edge{
    int f,t;
}l[MAXN << 1];
int head[MAXN],next[MAXN << 1],tot;
void build(int f,int t){
    l[++ tot] = (edge){f,t};
    next[tot] = head[f];
    head[f] = tot;
}
void init(int n){
    tot = 0;
    for(int i = 1;i <= n;i ++)
        head[i] = -1;
}
int pd[MAXN];
bool check[MAXN];
int dfs(int u){
    for(int i = head[u];i != -1;i = next[i]){
        int t = l[i].t;
        if((t <= n && !need[t]) || check[t])continue;
        check[t] = true;
        if(pd[t] == -1 || dfs(pd[t]) == 1){
            pd[t] = u;
            return 1;
        }
    }
    return -1;
}
int T;
int main(){
    scanf("%d",&T);
    while(T --){
        scanf("%d",&n);
        memset(need,0,sizeof(need));
        memset(zx,0,sizeof(zx));
        memset(hj,0,sizeof(hj));
        tot = 0;
        memset(head,-1,sizeof(head));
        for(int i = 1;i <= n;i ++){
            scanf("%d",&zx[i]);
            if(!zx[i])need[i] = true;
        }
        for(int i = 1;i <= n;i ++){
            scanf("%d",&hj[i]);
            if(zx[i] && !hj[i])need[i] = true;
        }
        for(int i = 1;i <= n;i ++){
            for(int j = 1;j <= n;j ++){
                scanf("%d",&x);
                if(x && zx[j]){
                    build(i,j + n);
                }
            }
            if(zx[i] && !hj[i])build(i,i + n);
        }
        memset(pd,-1,sizeof(pd));
        bool flag = false;
        for(int i = 1;i <= n;i ++){
            if(!need[i])continue;
            if(pd[i] == -1){
            	memset(check,0,sizeof(check));
	        	if(dfs(i) == -1){
	        		flag = true;
	        		break;
	            }
            }
        }
        if(flag)printf("T_T\n");
        else printf("^_^\n");
    }
    return 0;
}
posted @ 2017-11-06 21:00  _平行  阅读(123)  评论(0编辑  收藏  举报