zoukankan      html  css  js  c++  java
  • hdu2444The Accomodation of Students

    思路:

    二分图判断+最大匹配模板

    二分图判断的方法很好想,没有离散的基础凭空给你个图让你判断也很容易想到染色法,简单的介绍下就是用queue来做,标记一个点为x则他所有的邻点都为x',然后递归的执行下去。

    接下来会面临一个比较有趣的问题,我们确定现在的图是二分图,然后我们要求它的最大匹配——这里涉及到一个很关键的问题,就是一个图我们说他自己是一个二分图,那么是他内部的一些点会分成两部分,分别写成两列变成了形式上的二分图。而我们用find求二分图的时候是分别写成两列的话是一个图的所有点,因此总数最后是要除以2的。

    AC代码:

    #include <iostream>
    #include <cstring>
    #include <queue>
    #define maxn 207
    #define INF 9999999
    using namespace std;
    
    int n,m;
    int G[maxn][maxn];
    int mark[maxn];
    int vis[maxn];
    int match[maxn];
    int x,y;
    
    bool find(int x)
    {
        for(int i = 1;i <= n;i++)
            if(!vis[i] && G[x][i])
            {
                vis[i] = 1;
                if(match[i]==-1 || find(match[i]))
                {
                    match[i] = x;
                    return true;
                }
            }
        return false;
    }
    
    int main()
    {
        while(cin>>n>>m)
        {
            int flag = 1;
            queue<int> qv;
            memset(G,0,sizeof(G));
            memset(vis,0,sizeof(vis));
            memset(mark,-1,sizeof(mark));
            int t1,t2;
            for(int i = 1;i <= m;i++)
            {
                cin>>t1>>t2;
                G[t1][t2] = G[t2][t1] = 1;
            }
            mark[1] = 0;
            qv.push(1);
            while(!qv.empty())
            {
                int col = qv.front();
                qv.pop();
                if(vis[col]) continue;
                vis[col] = 1;
                for(int i = 1;i <= n;i++)
                    if(G[col][i])
                    {
                        if(mark[i] == -1) {
                            mark[i] = mark[col]==0?1:0;
                            qv.push(i);
                        }
                        else if(mark[i] != mark[col])
                            continue;
                        else {
                            flag = 0;
                            break;
                        }
                    }
                if(flag == 0) break;
            }
            if(!flag) {
                cout<<"No"<<endl;
                continue;
            }
            int ans = 0;
            memset(match,-1,sizeof(match));
            for(int i = 1;i <= n;i++)
            {
                memset(vis,0,sizeof(vis));
                if(find(i)) ans++;
            }
            cout<<ans/2<<endl;
        }
        return 0;
    }
  • 相关阅读:
    Windows中一个22年的漏洞
    关于口令强度等级的设计
    360招聘网络安全攻防技术研究员
    法国出售给阿联酋的卫星可能含有后门组件
    2013年极客范最受欢迎的10篇博文
    利用WPS 2012/2013 0day针对中国政府部门的定向攻击
    Kingsoft Office Writer 2012 8.1.0.3385
    破解Google Gmail的https新思路
    设计自己的密码规则,实现强壮的自我保护
    电信级的RSA加密后的密码的破解方法
  • 原文地址:https://www.cnblogs.com/immortal-worm/p/5191225.html
Copyright © 2011-2022 走看看