HDU 2444 判断二分图+最大匹配
来源:互联网 发布:泗阳网络问政123456 编辑:程序博客网 时间:2024/05/19 23:00
//题意概述:给出一些人的关系,A认识B,B认识C,不代表A认识C,有一些双人房间,要求要相互认识的才能分进同一间,问能最多需要多少间房//题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2444//先判断是否是二分图,不是直接输出NO,是则进行求最大匹配#include <iostream>#include <queue>#include <vector>using namespace std;const int Nocolor = 0;const int White = 1;const int Black = 2;const int MAXN = 210;int color[MAXN]; vector<int>V[MAXN];bool used[MAXN];int link[MAXN]; int n;//染色法bool judge(int start){ queue<int>Q; Q.push(start); color[start] = White; //初始化源点为白色 while(!Q.empty()) { int now = Q.front(); Q.pop(); for(int i=0; i<V[now].size(); i++) //采用邻接表存图 { int temp = V[now][i]; if(color[temp] == Nocolor) { if(color[now] == White) { color[temp] = Black; } else if(color[now] == Black) { color[temp] = White; } Q.push(temp); } if(color[temp] == color[now]) { return false; } } } return true;}//匈牙利bool findPath(int u){ int size = V[u].size(); for(int i=0; i<size; i++) { int v = V[u][i]; if(!used[v]) { used[v] = true; if(link[v] == -1 || findPath(link[v])) //找到未匹配的边 { link[v] = u; return true; } } } return false;}int solve(){ int Count = 0; memset(link,-1,sizeof(link)); for(int i=1; i<=n; i++) { memset(used,0,sizeof(used)); if(findPath(i)) { Count++; } } return Count; }int main(){ int m; int a,b; int flag; //记录是否矛盾 while(cin>>n>>m) { //记得初始化 for(int i=1; i<=n; i++) { V[i].clear(); } memset(color, 0, sizeof(color)); while(m--) { cin>>a>>b; //无向图 V[a].push_back(b); V[b].push_back(a); } flag = 1; for(i=1; i<=n; i++) { if(color[i] == Nocolor && !judge(i)) { flag = 0; break; } } if(flag) { int ans = solve();//最大匹配数 cout<<ans/2<<endl; } else cout<<"No"<<endl;//不是二分图 } return 0;}