zoukankan      html  css  js  c++  java
  • P2055 [ZJOI2009]假期的宿舍

    题目链接

    我觉得二分图的难点就是在建图的思想上。对于这道题,同样是需要将题中的条件进行建图。理一下思路,看一下可以怎样转化:

    1.每个在学校的学生肯定可以睡自己的床,所以就自己向自己连边。

    2.每个人(不管在或不在学校,是不是学生)都可以睡自己认识的人的床。

    这两个条件还是挺好想的。然后就统计一下有多少需要的床,跑一遍二分图最大匹配,看是否满足条件即可。

    代码如下:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e6+7;
    const int N=550;
    int school[maxn];
    int home[maxn];
    int n,t;
    int relation[N][N];
    bool vis[maxn];
    int match[maxn];
    struct node{
        int nxt,to;
    }edge[maxn*2];
    int head[maxn],cnt;
    void add(int x,int y){
        edge[++cnt].nxt=head[x];
        edge[cnt].to=y;
        head[x]=cnt;
    }
    int ans,bed;
    bool dfs(int x){
        for(int i=head[x];i;i=edge[i].nxt){
            int v=edge[i].to;
            if(!vis[v]){
                vis[v]=true;
                if(!match[v]||dfs(match[v])){
                    match[v]=x;
                    return true;
                }
            }
        }
        return false;
    }
    int main(){
        scanf("%d",&t);
        while(t--){
            memset(match,0,sizeof(match));
            memset(head,0,sizeof(head));
            memset(vis,false,sizeof(vis));
            scanf("%d",&n);
            ans=0,bed=0,cnt=0;
            for(int i=1;i<=n;i++) scanf("%d",&school[i]);
            for(int i=1;i<=n;i++){
                scanf("%d",&home[i]);
                if(!home[i]&&school[i]){
                    //cout<<i<<" "<<i<<endl;
                    add(i,i);
                }    
                //自己和自己的床位连边。 
            }
            for(int i=1;i<=n;i++){
                if((!home[i]&&school[i])||!school[i]) bed++;
            } 
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    scanf("%d",&relation[i][j]);
                    if(relation[i][j]&&school[j]){
                        //cout<<i<<" "<<j<<endl;
                        add(i,j);
                    } 
                } 
            } 
            for(int i=1;i<=n;i++){ 
                if((school[i]&&!home[i])||!school[i]){
                    memset(vis,false,sizeof(vis));
                    if(dfs(i)) ans++; 
                }
            }
            if(ans>=bed) printf("^_^
    ");
            else printf("T_T
    ");
        }
        return 0;
    } 
    View Code
  • 相关阅读:
    react开发环境准备
    react介绍
    课程大纲
    Proving Equivalences HDU-2767 (tarjan缩点)
    tarjan求强连通分量 + 缩点 + 求割点割边
    树的重心(性质+模版)
    Educational Codeforces Round 93 (Rated for Div. 2)(A B C D)
    Friend-Graph HDU
    Codeforces Round #665 (Div. 2) (A B C D E)
    Matrix Again HDU
  • 原文地址:https://www.cnblogs.com/LJB666/p/11666568.html
Copyright © 2011-2022 走看看