Hdu 2444 The Accomodation of Students

 

大意:给你一些人,有些相互认识,有些不认识,问你是否能将不认识的分在一组,如果不能,输出No,如果可以,输出可以预定的双人间的最大值。

思路:

1、交叉染色法判断二分图。

2、二分图最大匹配。

我敲的时候出现了小错误,然后爆栈了。以为是DFS太多导致,于是我改用队列实现的交叉染色,过了。敲二分匹配时突然发现了一个小错误,明白了是这个导致了爆栈。然后回过头去改DFS实现的交叉染色,Hdu的数据实在是太水了,有些地方我一不小心改成错误的,还是过了,但这在UVA上是绝对过不了的,比如UVA 10004二分染色。

CODE:

 

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <queue>
using  namespace std;

const  int MAXN =  210;
const  int MAXM =  210* 210;

struct Edge
{
     int v, next;
}edge[MAXM];

int n, m;
int cnt;

int first[MAXN], link[MAXN];
bool vis1[MAXN], color[MAXN], vis2[MAXN];

void init()
{
    cnt =  0;
    memset(first, - 1sizeof(first));
    memset(vis1,  0sizeof(vis1));
    memset(color,  0sizeof(color));
    memset(link, - 1sizeof(link));
}

void read_graph( int u,  int v)
{
    edge[cnt].v = v;
    edge[cnt].next = first[u], first[u] = cnt++;
}

void read_graph2()
{
     while(m--)
    {
         int u, v;
        scanf( " %d%d ", &u, &v);
        read_graph(u, v);
        read_graph(v, u);
    }
}

queue< int> q;
int Bicolor( int src)
{
     while(!q.empty()) q.pop();
    vis1[src] =  1;
    q.push(src);
     while(!q.empty())
    {
         int u = q.front(); q.pop();
         for( int e = first[u]; e != - 1; e = edge[e].next)
        {
             int v = edge[e].v;
             if(!vis1[v])
            {
                vis1[v] =  1;
                color[v] = !color[u];  // 写错了,写成color[v] = !color[v]也过,Hdu数据太水了。
                q.push(v);
            }
             else  if(color[u] == color[v])  return  false;
        }
    }
     return  true;
// 队列实现的交叉染色 

/* int Bicolor(int u) //DFS实现的交叉染色 
{
    for(int e = first[u]; e != -1; e = edge[e].next)
    {
        int v = edge[e].v;
        if(!vis1[v])
        {
            vis1[v] = 1;
            color[v] = !color[u];
            Bicolor(v);
        }
        else if(color[u] == color[v]) return false; 
    }
    return true;
}
*/

int ED( int u)
{
     for( int e = first[u]; e != - 1; e = edge[e].next)
    {
         int v = edge[e].v;
         if(!vis2[v])
        {
            vis2[v] =  1// 写成vis2[1] = 1;爆栈了。。。 
             if(link[v] == - 1 || ED(link[v]))
            {
                link[v] = u;
                 return  true;
            }
        }
    }
     return  false;
}

void solve( int src)
{
     int ans =  0;
    vis1[src] =  1// 很重要,不然会WA。 
     if(!Bicolor(src))
    {
        printf( " No\n ");
         return ;
    }
     for( int i =  1; i <= n; i++) 
    {
        memset(vis2,  0sizeof(vis2));
         if(ED(i)) ans++;
    }
    printf( " %d\n ", ans/ 2);
}

int main()
{
     while(~scanf( " %d%d ", &n, &m))
    {
        init();
        read_graph2();
        solve( 1);
    }
     return  0;
}

 

你可能感兴趣的:(com)