• hdu2444(二分图的判断和最大匹配)


    题意:给出n个点,m条边,问是否是二分图,不是输出No,如果是输出二分图最大匹配。

    思路:先判断是否是二分图。这里运用染色法,这里用的dfs(用bfs也可以),原理就是相连两点不能是同一种颜色

    二分图最大匹配用匈牙利算法就行。具体看代码。

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #define inf 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    int color[250];
    int mat[250];
    int used[250];
    int n,m;
    vector<int> ve[250];
    
    bool dfs(int x,int c)//染色 
    {
        color[x]=c;
        int s=ve[x].size();
        for(int i=0;i<s;i++)
        {
            if(color[ve[x][i]]==c)//相连点同样颜色,不是二分图 
                return false;
            if(color[ve[x][i]]==0&&!dfs(ve[x][i],-c))//相连点还未染色,搜索相连点 
                return false;
        }
        return true;
    }
    
    bool solve()//判断是否是二分图 
    {
        memset(color,0,sizeof(color));
        for(int i=1;i<=n;i++)
        {
            if(!color[i])
            {
                if(!dfs(i,1))
                    return false;
            }
        }
        return true;
    }
    //匈牙利算法 
    bool find(int x)
    {
        int s=ve[x].size();
        for(int i=0;i<s;i++)
        {
            int v=ve[x][i];
            if(!used[v])
            {
                used[v]=1;
                if(!mat[v]||find(mat[v]))
                {
                    mat[v]=x;
                    return true;
                }
            }
        }
        return false;
    }
    
    int match()
    {
        int ans=0;
        memset(mat,0,sizeof(mat));
        for(int i=1;i<=n;i++)
        {
            memset(used,0,sizeof(used));
            if(find(i))
                ans++;
        }
        return ans;
    }
    int main()
    {
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            int u,v;
            for(int i=1;i<=n;i++)
                ve[i].clear();
            for(int i=0;i<m;i++)
            {
                scanf("%d%d",&u,&v);
                ve[u].push_back(v);
                ve[v].push_back(u);
            }    
            if(!solve())
                printf("No
    ");
            else
                printf("%d
    ",match()/2);
        }
        return 0;
    }
  • 相关阅读:
    ZOJ 3949 Edge to the Root( 树形dp)
    CCF201812-3 CIDR合并
    CF700E E. Cool Slogans
    BZOJ4552: [Tjoi2016&Heoi2016]排序
    BZOJ3238: [Ahoi2013]差异
    BZOJ4566: [Haoi2016]找相同字符
    Codeforces Global Round 1 A~F
    (HDU)1555-- How many days? (多少天)
    (HDU)1491-- Octorber 21st (校庆)
    (HDU)1465-- 不容易系列之一
  • 原文地址:https://www.cnblogs.com/xiongtao/p/11170718.html
Copyright © 2020-2023  润新知