【图论-二分图】学生的住宿
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
Sample Output
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;
}
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++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++高级程序员成长之路
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例
- C与C++之间相互调用实例方法讲解
- 解析C++中派生的概念以及派生类成员的访问属性