• BZOJ1433: [ZJOI2009]假期的宿舍


    【传送门:BZOJ1433


    简要题意:

      有n个人,给出一个关系图,表示人与人之间的认识关系,其中有若干个学生,每个学生在学校宿舍里都有一张床

      有一次放假,有些学生要回家,有些不回家,留在宿舍,那些不回家的学生会把自己认识的人(不一定是学生)带到学校来住,每个人都只会睡在自己直接认识的人的床上,请问是否能够将所有人都有地方住(回家的学生回家了,就相当于有地方住了)


    题解:

      很显然,二分图匹配

      将除了回家的学生的所有人,往这些人所认识所有学生连边(相当于向床连边),而不回家的学生也要向自己的床连边(怎么可能自己都不能睡自己的床)

      然后跑二分图匹配就行了


    参考代码:

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    int v[51],b[51];
    struct node
    {
        int x,y,next;
    }a[3100];int len,last[51];
    void ins(int x,int y)
    {
        len++;
        a[len].x=x;a[len].y=y;
        a[len].next=last[x];last[x]=len;
    }
    int match[110];
    int bk[110];
    bool findmuniu(int x,int t)
    {
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(bk[y]!=t)
            {
                bk[y]=t;
                if(match[y]==0||findmuniu(match[y],t)==true)
                {
                    match[y]=x;
                    return true;
                }
            }
        }
        return false;
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            int n;
            scanf("%d",&n);
            for(int i=1;i<=n;i++) scanf("%d",&v[i]);
            for(int i=1;i<=n;i++) scanf("%d",&b[i]);
            len=0;memset(last,0,sizeof(last));
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    int x;
                    scanf("%d",&x);
                    if(x==1||i==j)
                    {
                        if(v[i]==1&&b[i]==1) continue;
                        if(v[j]==1) ins(i,j+n);
                    }
                }
            }
            memset(match,0,sizeof(match));
            memset(bk,0,sizeof(bk));
            bool bz=false;
            for(int i=1;i<=n;i++)
            {
                if(v[i]==0||(v[i]==1&&b[i]==0))
                {
                    if(findmuniu(i,i)==false)
                    {
                        printf("T_T
    ");bz=true;
                        break;
                    }
                }
            }
            if(bz==false) printf("^_^
    ");
        }
        return 0;
    }

     

  • 相关阅读:
    C++Primer中文版(第4版)第五章习题答案
    C++Primer中文版(第4版)第四章习题答案
    利用矩阵奇异值分解对图像进行压缩
    利用奇异值分解压缩图像
    程序莫名其妙地老死
    图像边沿平滑处理的matlab实现
    Zend Server搭建网站备注
    利用矩阵的n次方求图的连通性
    matlab增加数组元素的效率分析
    PHP语法总结
  • 原文地址:https://www.cnblogs.com/Never-mind/p/8087481.html
Copyright © 2020-2023  润新知