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

    原题链接:https://www.luogu.org/problem/show?pid=2055

    其实本题除了建边之外几乎与二分图最大匹配模板题没什么区别。

    二分图的一边的人,一边为床。。。

    如果本校学生且回家,那么就没他什么事情了,他并不需要床铺。如果是本校学生但不回家,那么就可以向自己的床连一条边,因为下面的邻接矩阵中并没有给出这种方案,但它是存在的。外校学生的话,就要向自己认识的人的床连一条边。

    之后跑二分图最大匹配即可,检查匹配数是否能满足需求。

    本题有多组数据,一定记得把head,tot,cnt这些东西清空。不然就会像我在后面的几组数据中WA到怀疑人生。

    #include<cstdio>
    #include<cstring>
    void read(int &y)
    {
        y=0;char x=getchar();
        while(x<'0'||x>'9') x=getchar();
        while(x>='0'&&x<='9')
        {
            y=y*10+x-'0';
            x=getchar();
        }
    }
    struct edge
    {
        int u,v;
    }e[10005];
    int t,n,tot,sum,x,cnt;
    int d[55],z[55];
    int vis[105],head[105],match[105];
    void add(int u,int v)
    {
        e[++cnt].u=head[u];
        e[cnt].v=v;
        head[u]=cnt;
    }
    int dfs(int x)
    {
        for(int i=head[x];i;i=e[i].u)
        {
            int t=e[i].v;
            if(vis[t]==1) continue;
            vis[t]=1;
            if(match[t]==0||dfs(match[t]))
            {
                match[t]=x;
                return 1;
            } 
        }
        return 0;
    }
    int main()
    {
        read(t);
        while(t--)
        {
            read(n);
            memset(head,0,sizeof(head));cnt=0;tot=0;//WA WA WA
            for(int i=1;i<=n;i++) read(d[i]);
            for(int i=1;i<=n;i++)
            {
                read(z[i]);
                if(z[i]==0&&d[i]==1) add(i,i);
                if(d[i]==0||(z[i]==0&&d[i]==1)) tot++;
            }
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    read(x);
                    if(x==1&&d[j]==1) add(i,j);
                }
            }
            memset(match,0,sizeof(match));
            sum=0;
            for(int i=1;i<=n;++i)
            {
                if((d[i]==1&&z[i]==0)||d[i]==0)
                {
                    memset(vis,0,sizeof(vis));
                    if(dfs(i)) sum++;
                }
            }
            if(sum>=tot) printf("^_^
    ");
            else printf("T_T
    ");
        }
        return 0;
    }
  • 相关阅读:
    MYSQL增量备份与恢复
    Centos7上MariaDB数据库启动问题解决
    mysql数据库的常用命令
    mysql数据库用户权限设置
    使mysql数据库支持简体中文
    如何在mysql数据库中开启使用tab键补全功能
    忘记mysql超户密码的解决方法
    Excel教程(复习)
    MySQL教程(复习)
    Linux教程(复习)
  • 原文地址:https://www.cnblogs.com/zeroform/p/7722102.html
Copyright © 2011-2022 走看看