zoukankan      html  css  js  c++  java
  • BZOJ 1433 && Luogu P2055 [ZJOI2009]假期的宿舍 匈牙利算法

    刚学了匈牙利正好练练手(我不会说一开始我写错了)(怕不是寒假就讲了可是我不会)

    把人看做左部点,床看作右部点

    建图:(!!在校相当于有床,不在校相当于没有床 但是要来学校)

      1.在校的 不走的人 自己和自己的床连边;

      2.不在校的人或在校不回家的人 和 认识的 并且 在校的人 的床 连边;

    于是统计一下需要几张床,再跑匈牙利算法、、、看看够不够。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define R register int
    using namespace std;
    inline int g() {
        R ret=0; register char ch; while(!isdigit(ch=getchar()));
        do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret;
    }
    int t,n,cnt,ans,tot;
    int vr[10010],nxt[10010],fir[101],pre[101];
    inline void add(int u,int v) {vr[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt;}
    bool vis[101],h[101],s[101];
    bool dfs(int u) {
        for(R i=fir[u];i;i=nxt[i]) {R v=vr[i];
            if(vis[v]) continue; vis[v]=true;
            if(!pre[v]||dfs(pre[v])) {pre[v]=u; return true;}
        } return false;
    }
    signed main() {
        t=g();
        while(t--) { cnt=tot=ans=0;
            memset(pre,0,sizeof(pre)),memset(fir,0,sizeof(fir)),memset(nxt,0,sizeof(nxt)),memset(vr,0,sizeof(vr));
            n=g(); for(R i=1;i<=n;++i) s[i]=g();
            for(R i=1;i<=n;++i) {
                h[i]=g(); if(!h[i]&&s[i]) add(i,i+n),add(i+n,i);
            }
            for(R i=1;i<=n;++i) for(R j=1,x;j<=n;++j) {
                x=g();               
                if(x&&i!=j) {
                    if(s[j]&&((s[i]&&!h[i])||!s[i])) add(i,j+n),add(j+n,i);
                    if(s[i]&&((s[j]&&!h[j])||!s[j])) add(j,i+n),add(i+n,j);
                }
            }
            for(R i=1;i<=n;++i) if(!s[i]||(s[i]&&!h[i])) ++tot;
            for(R i=1;i<=n;++i) if(!s[i]||(s[i]&&!h[i])) {
                memset(vis,0,sizeof(vis)); ans+=dfs(i);
            } ans==tot?printf("^_^
    "):printf("T_T
    ");
        }
    }

    然而有种更厉害的建图,但是我不会。。。哪位大佬给讲讲QAQ,如下:

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define R register int
    using namespace std;
    inline int g() {
        R ret=0; register char ch; while(!isdigit(ch=getchar()));
        do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret;
    }
    int t,n,cnt,ans,tot;
    int vr[2510],nxt[2510],fir[51],pre[51];
    inline void add(int u,int v) {vr[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt;}
    bool vis[51],h[51],s[51];
    bool dfs(int u) {
        for(R i=fir[u];i;i=nxt[i]) {R v=vr[i];
            if(vis[v]) continue; vis[v]=true;
            if(!pre[v]||dfs(pre[v])) {pre[v]=u; return true;}
        } return false;
    }
    signed main() {
        t=g();
        while(t--) { cnt=tot=ans=0;
            memset(pre,0,sizeof(pre)),memset(fir,0,sizeof(fir)),memset(nxt,0,sizeof(nxt)),memset(vr,0,sizeof(vr));
            n=g(); for(R i=1;i<=n;++i) s[i]=g();
            for(R i=1;i<=n;++i) {
                h[i]=g(); if(!h[i]&&s[i]) add(i,i);
            }
            for(R i=1;i<=n;++i) for(R j=1,x;j<=n;++j) {
                x=g(); if(x&&s[j]) add(i,j);
            }
            for(R i=1;i<=n;++i) if(!s[i]||(s[i]&&!h[i])) ++tot;
            for(R i=1;i<=n;++i) if(!s[i]||(s[i]&&!h[i])) {
                memset(vis,0,sizeof(vis)); ans+=dfs(i);
            } ans==tot?printf("^_^
    "):printf("T_T
    ");
        }
    }

    2019.04.14

  • 相关阅读:
    几种简单排序算法
    【转】虚拟机下CentOS7开启SSH连接
    【转】SignalR来做实时Web聊天
    加密算法(DES,AES,RSA,MD5,SHA1,Base64)比较和项目应用
    C#加密解密(DES,AES,Base64,md5,SHA256,RSA,RC4)
    【C#公共帮助类】给大家分享一些加密算法 (DES、HashCode、RSA、AES等)
    对称加密与非对称加密
    PowerDesigner概念模型与物理模型相互转换及导出数据字典
    SQO2008配置管理工具服务显示远程过程调用失败
    MongoDB学习笔记-数据格式及数据类型
  • 原文地址:https://www.cnblogs.com/Jackpei/p/10707186.html
Copyright © 2011-2022 走看看