• hrbeu 哈工程The Accomodation of Students


    经典题目,HDU上也有,给定一个无向图,先判断是否为二分图,不是输出No,是的话,输出最大匹配,算是一个模板题

    1.一个图不存在奇环则是二分图

    2.二分图最大匹配用匈牙利算法

    #include <cstdio>
    #include <cstring>
    #define N 210
    int g[N][N];  //无向图领接表
    int mat[N],cov[N],vis[N],c[N];
    int n,m;
    
    void input()
    {
        memset(g,0,sizeof(g));
        for(int i=1; i<=m; i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            int t;
            t=++g[u][0];
            g[u][t]=v;
            t=++g[v][0];
            g[v][t]=u;
        }
        return ;
    }
    
    int dfs(int u ,int p) //u是当前顶点,p是它的前驱,c表示奇偶
    {
        vis[u]=1;
        for(int i=1; i<=g[u][0]; i++)
        {
            int v=g[u][i];
            if(v==p) continue;   //如果是前驱跳过,不能走回头
            if(vis[v]==0)       //还没访问过的点,直接访问
            {
                c[v]=!c[u];
                if(dfs(v,u)) 
                    return 1;
            }
            else if(vis[v]==1)  //已经访问过,那么就是环,那么就判断是不是奇环
            {
                if( c[u]==c[v] )  //加上成环的边后是奇数,那么就是奇环
                    return 1;
            }
        }
        return 0;
    }
    
    int find(int u)
    {
        for(int i=1; i<=g[u][0]; i++)
        {
            int v=g[u][i];
            if(!cov[v])
            {
                cov[v]=1;
                if(!mat[v] || find(mat[v]))
                {
                    mat[v]=u;
                    return 1;
                }
            }
        }
    
        return 0;
    }
    void max_match()
    {
        int ans=0;
        memset(mat,0,sizeof(mat));
        for(int i=1; i<=n; i++)
        {
            memset(cov,0,sizeof(cov));
            ans+=find(i);
        }
    /*
        printf("mat数组\n");
        for(int i=1; i<=n; i++)
            printf("%d ",mat[i]);
        printf("\n");
        printf("ans=%d\n",ans);
    */
    
        printf("%d\n",ans/2);
    }
    int main()
    {
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            input();
            memset(vis,0,sizeof(vis));
            memset(c,0,sizeof(c));
            int flag=1;
            for(int i=1; i<=n; i++)
                if(!vis[i])
                {
                    if(dfs(i,0))
                    {flag=0; break;}
                }
            if(!flag)
                printf("No\n");
            else
                max_match();
        }
        return 0;
    }
  • 相关阅读:
    type( ) 和 isinstance( )
    el-input-number element计数器设置自定义小数位数
    Electron-Vue起步
    SmartGit破解使用的个人方法
    js 之 数组去重
    Vue动态class
    vue项目如何(友好的)刷新当前页
    Promise()与链式执行
    Vue过渡&循环切换&放大缩小动画
    css Margin塌陷问题(margin属性撑不开盒子)
  • 原文地址:https://www.cnblogs.com/scau20110726/p/2790064.html
Copyright © 2020-2023  润新知