您的位置:首页 > 编程语言 > C语言/C++

【图论-二分图】学生的住宿

2016-04-09 09:46 435 查看
【图论-二分图】学生的住宿
Time Limit:1000MS  Memory Limit:65536K
Description

有n个学生,有m对人是认识的,每一对认识的人能分到一间房,问能否把n个学生分成两部分,每部分内的学生互不认识,而两部分之间的学生认识。如果可以分成两部分,就算出房间最多需要多少间,否则就输出No。

There 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. But this may not imply that A and C know each other.

Now you are given all pairs of students who know each other. Your task is to divide the students into two groups so that any two students in the same group don't know each other.If this goal can be achieved, then arrange them into double rooms. Remember, only
paris appearing in the previous given set can live in the same room, which means only known students can live in the same room.

Calculate the maximum number of pairs that can be arranged into these double rooms.

Input

输入有多组数据。

对于每组数据的第一行为两个整数n和m(1 < n <= 200), 即有n个学生和m队互相认识的学生。

接下来有m行,每行两个数,即互相认识的学生。

For each data set:

The first line gives two integers, n and m(1<n<=200), indicating="" there="" are="" n="" and="" pairs="" of="" students="" who="" know="" each="" other.="" The="" next="" m="" lines="" give="" such="" pairs.=""

Proceed to the end of file.

Output

如果可以分成两部分,就算出房间最多需要多少间,否则就输出No。

If these students cannot be divided into two groups, print "No". Otherwise, print the maximum number of pairs that 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


Hint

题目:http://acm.hdu.edu.cn/showproblem.php?pid=2444

二分图判断+最大匹配+AC

#include <cstdio>

#include <vector>

#include <cstring>

using namespace std;

int M,N,ans;

int link[200+1];//link数组重复利用做color和pre

int flag[200+1],G[200+1][200+1];//邻接矩阵

vector<int> X,Y;

inline bool is_binary_graph(int s,int c)//判断二分图

{

 link[s]=c;//染色

 if(c==1)X.push_back(s);

 else Y.push_back(s);//划分为X和Y两个集合

 for(int i=1;i<=N;i++)

     if(!G[s][i])continue;

     else if(link[i]==link[s])return false;//若颜色相同,则返回false

     else if(!link[i]&&!is_binary_graph(i,-c))return false;//dfs

 return true;

}

inline bool find(int s)//寻找增广路

{

 for(int i=0;i<Y.size();i++)

 {

  if(!flag[Y[i]]&&G[s][Y[i]])

  {

   flag[Y[i]]=true;

   if(link[Y[i]]==0||find(link[Y[i]]))//若Y[i]尚未匹配或找到增广路

   {

    link[Y[i]]=s;

    return true;

   }

  }

 }

 return false;

}

inline int max_match()//求最大匹配数

{

 memset(link,0,sizeof(link));

 for(int i=0;i<X.size();i++)

 {

  memset(flag,0,sizeof(flag));//初始化

  if(find(X[i]))ans++;

 }

 return ans;

}

int main()

{

 while(scanf("%d%d",&N,&M)!=EOF)

 {

  memset(link,0,sizeof(link));

  memset(G,0,sizeof(G));

  ans=0;

  X.resize(0);Y.resize(0);//初始化

     for(int i=0,u,v;i<M;i++)

         scanf("%d%d",&u,&v),G[u][v]=G[v][u]=true;

     if(!is_binary_graph(1,1)){puts("No");continue;}

     printf("%d\n",max_match());

 }

 return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++ 二分图 图论