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;
}

原文地址:https://www.cnblogs.com/shoulinniao/p/11311256.html

时间: 2024-08-06 04:25:07

hdu5285-wyh2000 and pupil-(染色法二分图判定)的相关文章

二分图判定+点染色 BestCoder Round #48 ($) 1002 wyh2000 and pupil

题目传送门 1 /* 2 二分图判定+点染色:因为有很多联通块,要对所有点二分图匹配,若不能,存在点是无法分配的,no 3 每一次二分图匹配时,将点多的集合加大最后第一个集合去 4 注意:n <= 1,no,两个集合都至少有一人:ans == n,扔一个给另一个集合 5 */ 6 #include <cstdio> 7 #include <algorithm> 8 #include <cstring> 9 #include <cmath> 10 #in

HDU 5285 wyh2000 and pupil (DFS染色判二分图 + 贪心)

wyh2000 and pupil Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 1040    Accepted Submission(s): 331 Problem Description Young theoretical computer scientist wyh2000 is teaching his pupils. W

二分图的判定(染色法)和二分图最大匹配(匈牙利)算法及模板

定义 二分图也称二部图,是图论里的一种特殊模型,也是一种特殊的网络流.其最大的特点在于,可以将图里的顶点分为两个集合,且集合内的点没有直接关联,如下图所示. 如果某个图为二分图,那么它至少有两个顶点,且其所有回路的长度均为偶数,任何无回路的的图均是二分图. 1.染色法判断二分图 染色法是对每一个点深搜,与这个点连接的点颜色与此点相反,如果存在环且是偶数环或则不存在环,则满足该条件,如果存在奇数环则不满足(推出矛盾) #include<iostream> #include<cstring&

hdu 5285 wyh2000 and pupil(二分图判定)

对每两个不认识的人连一条边,则此题可转化为二分图判定(二分图可有多个). 如果有一部分图判定为不是二分图,则输出“Poor wyh”. 否则,分别累加每个二分图的最多的颜色数. #include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <string> #include <stack> #include <cmat

交叉染色法判断二分图

题目链接:传送门 题目大意:给你一副无向联通图,判断是不是二分图 题目思路:交叉染色法 下面着重介绍下交叉染色法的定义与原理 首先任意取出一个顶点进行染色,和该节点相邻的点有三种情况: 1.未染色    那么继续染色此节点(染色为另一种颜色) 2.已染色但和当前节点颜色不同      跳过该点 3.已染色并且和当前节点颜色相同       返回失败(该图不是二分图) 下面在拓展两个概念: (1) 如果一个双连通分量内的某些顶点在一个奇圈中(即双连通分量含有奇圈),那么这个双连通分量的其他顶点也在

染色法判断二分图

染色法判断二分图 给一个无向图,判断是否是二分图. 这很简单: 1.把节点1染为1. 2.搜索各点,遍历与此点u相连的点v. 3.如果点v没颜色,把它染为与点u相反的颜色(即-u). 4.如果有颜色,则比较v与u颜色是否相同.若相同,返回0:若不同,则继续. 代码: 1 #include<cstdio> 2 #define N 420000 3 int head[N],next[N],to[N],rs[N],n,m,a,b,y,num; 4 int dfs(int x){ 5 for(int

UVA 1364 - Knights of the Round Table (找双连通分量 + 二分图染色法判断)

都特么别说话,我先A了这道题! 卧槽啊.....! 题意来自 kuangbin: 亚瑟王要在圆桌上召开骑士会议,为了不引发骑士之间的冲突, 并且能够让会议的议题有令人满意的结果,每次开会前都必须对出席会议的骑士有如下要求: 1.  相互憎恨的两个骑士不能坐在直接相邻的2个位置: 2.  出席会议的骑士数必须是奇数,这是为了让投票表决议题时都能有结果. 注意:1.所给出的憎恨关系一定是双向的,不存在单向憎恨关系. 2.由于是圆桌会议,则每个出席的骑士身边必定刚好有2个骑士. 即每个骑士的座位两边都

染色法判断是否是二分图 hdu2444

用染色法判断二分图是这样进行的,随便选择一个点, 1.把它染成黑色,然后将它相邻的点染成白色,然后入队列 2.出队列,与这个点相邻的点染成相反的颜色 根据二分图的特性,相同集合内的点颜色是相同的,即 但是如果这个图不是二分图,那么就会这样 把与1相邻的点2,3染成白色,然后入队列,然后2出队列,要把与2相邻的点2,3染成黑色,但是都染过了,所以不用染色 但是3的颜色应该与2相反(如果是二分图的话),可是没有相反,所以就不是二分图 1 #include <stdio.h> 2 #include

poj2942 双联通分量+交叉染色法判断二分图

Knights of the Round Table Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 11805   Accepted: 3870 Description Being a knight is a very attractive career: searching for the Holy Grail, saving damsels in distress, and drinking with the oth