题意:先判断学生能否分成两块互不认识的集体,然后找出这两块集体的最大匹配
吐槽:迷之WA了几次,后来把判断是否是二分图弄成函数写在外面就ok了。
/************************************************ Author :DarkTong Created Time :2016/8/1 13:02:46 File Name :Hdu_2444.cpp *************************************************/ //#include <bits/stdc++.h> #include <cstdio> #include <cstring> #include <queue> using namespace std; const int maxn = 200 + 10; int w[maxn][maxn], n, m; int Left[maxn]; bool used[maxn]; bool match(int i) { for(int j=1;j<=m;++j) if(w[i][j]&&!used[j]) { used[j] = true; if(!Left[j]||match(Left[j])) { Left[j] = i; return true; } } return false; } //返回最大匹配数 int hungary() { int res=0; memset(Left, 0, sizeof(Left)); for(int i=1;i<=n;++i) { memset(used, 0, sizeof(used)); if(match(i)) res++; } return res; } int vis[maxn]; bool bfs() { memset(vis, 0, sizeof(vis)); for(int i=1;i<=n;++i) { if(!vis[i]) { queue<int> q; q.push(i); vis[i] = 1; while(!q.empty()) { int t = q.front(); q.pop(); for(int j=1;j<=n;++j) { if(w[t][j]) { if(vis[j]==vis[t]) return false; else if(vis[j]==0) { vis[j] = - vis[t]; q.push(j); } } } } } } return true; } int main() { int T, cas=1, k; while(scanf("%d%d", &n, &k)==2) { memset(w, 0, sizeof(w)); memset(vis, 0, sizeof(vis)); m=n; int u, v; for(int i=1;i<=k;++i) { scanf("%d%d", &u, &v); w[v][u] = w[u][v]=1; } if(!bfs()) { puts("No"); continue; } int ans = hungary(); printf("%d\n", ans>>1); } return 0; }
时间: 2024-10-12 03:07:20