【ZJOI2009]休日四半期ハンガリーと一致する二部グラフを

【ZJOI2009]休日四半期ハンガリーと一致する二部グラフを

ベッドに対応するもの、床のそれぞれは、二部グラフマッチングを推測することができるつ以上を選択することができます。

ベッドには、唯一の大学の学生によって提供され、キャンパスや学校で、学校の人々の2種類の外に住むためにそこに、ベッドを必要とすることができます。最後の統計は、二部グラフ数が等しい必要があるかどうかにベッドの数に一致します。

詳細、慎重な節度に注意。

#include <cstdio>
#include <cstring>
#define MAXN 100
using namespace std;
int head[MAXN],nxt[10000],vv[10000],tot;
inline void add_edge(int u, int v){
    vv[++tot]=v;
    nxt[tot]=head[u];
    head[u]=tot;
}
bool ins[MAXN],home[MAXN];
int n,want;
void init(){
    memset(ins, 0, sizeof(ins));
    memset(home, 0, sizeof(home));
    memset(head, 0, sizeof(head));
    memset(nxt, 0, sizeof(nxt));
    memset(vv, 0, sizeof(vv));
    tot=0;
    want=0;
}
bool vis[MAXN];
int m[MAXN];
bool dfs(int u){
    for(int i=head[u];i;i=nxt[i]){
        int v=vv[i];
        if(vis[v]) continue;
        vis[v]=1;
        if(m[v]==0||dfs(m[v])){
            m[v]=u;
            return 1;
        }
    }
    return 0;
}
int main(){
    int T;
    scanf("%d", &T);
    while(T--){
        scanf("%d", &n);
        init();
        for(int i=1;i<=n;++i) scanf("%d", &ins[i]);
        for(int i=1;i<=n;++i){
            scanf("%d", &home[i]);
            if(ins[i]&&home[i]==0) add_edge(i, i);
        }
        for(int i=1;i<=n;++i)
            for(int j=1;j<=n;++j){
                int t;scanf("%d", &t);
                if(t==1&&ins[j]) add_edge(i, j);
            }
        memset(m, 0, sizeof(m));
        int ans=0;
        for(int i=1;i<=n;++i)
            if(!ins[i]||(ins[i]&&home[i]==0)){
                ++want;
                memset(vis, 0, sizeof(vis));
                if(dfs(i)) ++ans;
            }
        //printf("%d\n%d", want, ans);
        if(ans==want) printf("^_^\n");
        else printf("T_T\n");
    }
    return 0;
}

おすすめ

転載: www.cnblogs.com/santiego/p/11203099.html