hdu 244 The Accoodation of Students(二分割図の判断+ハンガリーアルゴリズム)

5122 ワード

テーマリンク:http://acm.hdu.edu.cn/showproblem.php?pid=2444
The Accompodation of Students
Time Limit:5000/1000 MS(Java/Others)    メモリLimit:32768/32768 K(Java/Others)
Total Submission(s):3703    Acceepted Submission(s):1740
Problem Description
The re are a group of students.Some of them may know each other,while others don't.For example,A and B know each other,B and C know each other.Butthisismay not imply that A and C know each othe.Now YouYouYou arare givel pairs of studes whoknow aah h h h.Your tass to divide the studedestudnts in in into to to to to to totototototototototototototototototototototototototototototototototototototototototototototototototototototototototototototototototototototototototototototototototototototototototototototototototouble rooms.Remember,only paris apparing in the previous given set can live in the same room,which means only known students can live in the same room.Calculate the maximnumber of pairs can can ranged inthe toubros.
 
Input
For each data set:The first line gives two integers,n and m(1 
Output
If these students cannot be divided into two groups、print“No”.Otherwise、print the maximnumber of pairs can be arranged in those rooms.
 
Sample Input

   
   
   
   
4 4 1 2 1 3 1 4 2 3 6 5 1 2 1 3 1 4 2 5 3 6
 
Sample Output

   
   
   
   
No 3
 
ソurce
2008 Asia Harbin Regional Contact Online
 
Recommund
gaojie   |   We have carefully selected several simiar probles for you:  2438 2443 2442 2441 2440 
学生二人をグループに分けて、グループ内の人とお互いに知らないようにします。可能であれば最大のグループ数を出力します。Noを出力します。
問題解決の考え:「隣点塗りつぶし」を使って二点図、0と1の染色かどうかを判断し、まず一つの点を選んで染色し、その隣の点を染色しているかどうか、もし染色していないなら、それを現在の点と違った色に染めて、すでに染めたらbfsの検索を開始します。隣の二つの点の色が同じなら、二点図ではありません。もし違ったら判断を続けます。
詳細はコードを参照してください
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>

using namespace std;

bool Map[210][210];
bool vis[210];//     
int ok[210];//     
int judge[210];//       0-1 
int n,m;

bool Bfs()
{
    queue<int>q;
    q.push(1);//            
    //vis[1]=1;
    for (int i=1; i<=n; i++)//       -1
        judge[i]=-1;
    judge[1]=0;//         0
    while(!q.empty())//          
    {
        int s=q.front();
        q.pop();
        for(int i=1;i<=n;i++)
        {
            if(Map[s][i]==1)
            {
                if(judge[i]==-1)//       
                {
                    judge[i]=(judge[s]+1)%2;//     ,             
                    q.push(i);
                }
                else
                {
                    if(judge[i]==judge[s])//     ,          ,        
                        return false;
                }
            }
        }
    }
    return true;
}
/*bool bfs()//        
{
    int v,start=0,end=1;
    queue[0]=1;
    for (int i=0; i<=n; i++)
        judge[i]=-1;
    v=queue[start];
    judge[1]=0;
    memset(vis,0,sizeof(vis));

    while (start<end)
    {
        v=queue[start];
        for (int i=1; i<=n; i++)
        {
            if (Map[v][i])
            {
                if (judge[i]==-1)
                {
                    judge[i] = (judge[v]+1)%2;
                    queue[end++] = i;
                }
                else
                {
                    if(judge[i] == judge[v])
                        return false;
                }
            }
        }
        start++;
    }
    return true;
}
*/

bool Find(int x)
{
    for (int i=1; i<=n; i++)
    {
        if (Map[x][i]==1&&!vis[i])
        {
            vis[i]=1;
            if (!ok[i])
            {
                ok[i]=x;
                return true;
            }
            else
            {
                if (Find(ok[i])==true)
                {
                    ok[i]=x;
                    return true;
                }
            }
        }
    }
    return false;
}

int main()
{
    while (~scanf("%d%d",&n,&m))
    {
        int a,b;
        memset(Map,0,sizeof(Map));
        for (int i=1; i<=m; i++)
        {
            scanf("%d%d",&a,&b);
            Map[a][b]=Map[b][a]=1;
        }
        if(!Bfs())
        {
            printf("No
"); continue; } //the maximum number of pair int num = 0; memset(ok,0,sizeof(ok)); for(int i=1; i<=n; i++) { memset(vis,0,sizeof(vis)); if(Find(i)) num++; } printf("%d
",num/2); } return 0; }