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;
    }
  • 相关阅读:
    明确架构目标
    是什么浪费了我的时间
    精益求精,抑或得过且过[转]
    web界面应用的十种常见技术
    我对软件优化的一些想法
    最新31个非常棒的 Photoshop 网页设计教程
    sql2005提示工具程序
    转载:一篇深入了解.NET中栈和堆较好的文章
    推荐18个非常棒的Web和移动开发框架
    介绍一下这些工具FishAspnetLoader
  • 原文地址:https://www.cnblogs.com/immortal-worm/p/5191225.html
Copyright © 2011-2022 走看看