zoukankan      html  css  js  c++  java
  • hdu5285-wyh2000 and pupil-(染色法二分图判定)

    http://acm.hdu.edu.cn/showproblem.php?pid=5285

    题意:把互不认识的人分到两个组,第一组人数尽可能多。

    题解:把互不认识的人连起来,当作二分图,二分图可能有多个,对于没有连线的点,扔到第一个图里。二色法对每个二分图染色,记录每个图比较多的颜色的数量累计到答案里。

    特判坑:n<=1 或者 m==0

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<math.h>
    #include<string>
    #include<map>
    #include<queue>
    #include<stack>
    #include<set>
    #define ll long long
    #define inf 0x3f3f3f3f
    using namespace std;
    
    int n,m;
    
    vector<int>a[100005];
    int color[100005];
    int zero,one;
    int minn,maxx;
    bool flag;
    
    void bfs(int x)
    {
        queue<int>que;///对x点进行广搜,二色法,一个标记为0,另一个标记为1
        zero=one=0;
        zero++;
        que.push(x);
        color[x]=0;
        while(!que.empty()&&flag)
        {
            int now=que.front();
            que.pop();
            int c=color[now];
            int len=a[now].size();
            for(int i=0;i<len;i++)
            {
                int next=a[now][i];
                if(color[next]==-1)///如果没有被染色过,
                {
                    que.push(next);
                    if(c==0)
                        color[next]=1,one++;
                    else
                        color[next]=0,zero++;
                }
                else ///被染色过
                {
                    if( color[next]==c )
                    {
                        flag=false;
                        break;
                    }
                }
            }
    
        }
    }
    
    
    int main()//hdu5285
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
    
            scanf("%d%d",&n,&m);
    
            for(int i=1;i<=n;i++)
                a[i].clear();
            memset(color,-1,sizeof(color));
            minn=maxx=0;
            flag=true;
    
            if(n<=1)
            {
                printf("Poor wyh
    ");
                continue;
            }
            if(m==0)///特判,否则全部染成0色
            {
                printf("%d 1
    ",n-1);
                continue;
            }
    
            while(m--)
            {
                int u,v;
                scanf("%d%d",&u,&v);
                a[u].push_back(v);
                a[v].push_back(u);
            }
            int no=0;///没有被染色的点,其中第一组尽量多,则把没有染色的加到多的那一边去
            for(int i=1;i<=n && flag;i++)
            {
    
                if(color[i]==-1 && a[i].size() )///没有被染色的点 并且 不是独立的
                {
                    bfs(i);
                    if(zero<one)
                        swap(zero,one);
                    maxx+=zero;
                    minn+=one;
                }
                else if(color[i]==-1 && a[i].size()==0)///独立的点染成颜色0,0是第一组,较多的那一组
                {
                    color[i]=0;
                    maxx++;
                }
            }
            if(flag)
                printf("%d %d
    ",maxx,minn);
            else
                printf("Poor wyh
    ");
        }
    
        return 0;
    }
  • 相关阅读:
    Nginx记录-nginx 负载均衡5种配置方式(转载)
    Nginx记录-Nginx基础(转载)
    Hadoop记录-Hadoop集群重要监控指标
    Hbase记录-HBase性能优化指南
    Hadoop记录-hadoop集群常见问题汇总
    Hadoop记录-Hadoop集群添加节点和删除节点
    Linux记录-安装LAMP和R环境
    SQL记录-ORACLE 12C初体验
    Hbase记录-hbase部署
    接口测试基础与工具
  • 原文地址:https://www.cnblogs.com/shoulinniao/p/11311256.html
Copyright © 2011-2022 走看看