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;
    }
  • 相关阅读:
    BZOJ 2244 [SDOI2011]拦截导弹 (三维偏序CDQ+线段树)
    BZOJ 2141 排队 (三维偏序CDQ+树状数组)
    BZOJ 3295 [CQOI2011]动态逆序对 (三维偏序CDQ+树状数组)
    BZOJ 3262 陌上花开 (三维偏序CDQ+树状数组)
    BZOJ 4012 [HNOI2015]开店 (树分治+二分)
    CF1090H Linearization
    BZOJ 4141 [Thu Summer Camp 2013]魔塔
    luogu P4654 [CEOI2017]Mousetrap
    luogu P4548 [CTSC2006]歌唱王国
    [总结] min-25筛
  • 原文地址:https://www.cnblogs.com/zeroform/p/7722102.html
Copyright © 2011-2022 走看看