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) memset(x,c,sizeof(x))
#define qwq(x) for(edge *o=head[x];o;o=o->next)
int read(){
    int x=0;char c=getchar();
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) x=x*10+c-'0',c=getchar();
    return x;
}
const int nmax=55;
int a[nmax],b[nmax],mh[nmax];
bitset<nmax>vis;
struct edge{
    int to;edge *next;
};
edge es[nmax*nmax],*pt=es,*head[nmax];
void add(int u,int v){
    pt->to=v;pt->next=head[u];head[u]=pt++;
}
bool find(int x){
    qwq(x) if(!vis[o->to]){
        vis[o->to]=1;
        if(!mh[o->to]||find(mh[o->to])) {
            mh[o->to]=x;return 1;
        }
    }
    return 0;
}
int main(){
    int t=read();
    while(t--){
        clr(head,0);pt=es;clr(mh,0);
        int n=read(),u,cnt=0;
        rep(i,1,n) a[i]=read();
        rep(i,1,n) {
            b[i]=read();
            if(!a[i]||a[i]&&!b[i]) cnt++;
        }
        rep(i,1,n) {
          rep(j,1,n){
            u=read();
            if(u&&(!a[i]||a[i]&&!b[i])&&a[j]) add(i,j);
          }
          if(a[i]&&!b[i]) add(i,i);
        }
        int ans=0;
        rep(i,1,n){
            vis.reset();
            if(find(i)) ans++;
        }
        if(ans==cnt) printf("^_^
");
        else printf("T_T
");
    }
    return 0;
}

  

1433: [ZJOI2009]假期的宿舍

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 2297  Solved: 974
[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 ≤ 50,1 ≤ T ≤ 20。

Source

 
[Submit][Status][Discuss]
原文地址:https://www.cnblogs.com/fighting-to-the-end/p/5858080.html