hdu5285-wyh2000 and pupil-(染色法二分图判定)

Posted shoulinniao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n");
            continue;
        
        if(m==0)///特判,否则全部染成0色
        
            printf("%d 1\n",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\n",maxx,minn);
        else
            printf("Poor wyh\n");
    

    return 0;

 

以上是关于hdu5285-wyh2000 and pupil-(染色法二分图判定)的主要内容,如果未能解决你的问题,请参考以下文章

wyh2000 and pupil

HDU 5113 Black And White

hdu 5652 India and China Origins 并查集+二分

并查集(逆序处理):HDU 5652 India and China Origins

HDU 5833 Zhu and 772002

HDU 5627Clarke and MST