1. 程式人生 > 實用技巧 >HDU 2444 二分圖的判定+最大匹配

HDU 2444 二分圖的判定+最大匹配

xg

題意

  n個人,m個關係。對於第i個關係,x互相認識y。

  問能否把n個人分成兩組,使得一組裡的人互相不認識。

  如果能,則要開ans個房間,每個房間兩人,使得每個房間裡的人互相認識。

思路

  第一個問題就是01染色判斷能否染色成功。

  第二個問題裸最大匹配

#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <iomanip>
#include 
<algorithm> #include <queue> #include <stack> #include <set> #include <vector> #define bug cout<<"--------------"<<endl #define sp ' ' using namespace std; typedef long long ll; const int maxn = 8e4+10; int n,m,cnt; int tot = 0; int head[maxn],ver[maxn],edge[maxn],nextt[maxn];
void add(int x,int y) { ver[++tot] = y,nextt[tot] = head[x] , head[x] = tot; } int col[maxn],cun[maxn]; int flag = 0,tail = 0; int vis[maxn]; int tc = 0; int hc[maxn],vc[maxn],nc[maxn]; void add_c(int x,int y) { //cout<<x<<sp<<y<<endl; vc[++tc] = y,nc[tc] = hc[x] , hc[x] = tc; }
int dfs01(int s) { int v; queue<int>que; col[s]=0; que.push(s); while(que.size()) { int x =que.front(); que.pop(); if(col[x] == 0) cun[++tail] = x; for(int i=head[x]; i; i=nextt[i]) { int y = ver[i]; if(col[y]==-1) { col[y]=col[x]^1; que.push(y); } else if(col[y]==col[x]) { return 0; } } } return 1; } int match[maxn]; bool dfs(int x) { for(int i = head[x],y;i; i = nextt[i]){ if(!vis[y = ver[i]]){ vis[y] = 1; if(!match[y] || dfs(match[y])){ match[y] = x; return 1; } } } return 0; } void clearr() { memset(head,0,sizeof(head)); tot = 0; memset(col,-1,sizeof(col)); flag = 0; memset(vis,0,sizeof(vis)); memset(hc,0,sizeof(hc)); tc = 0; memset(match,0,sizeof(match)); tail = 0; } int main() { //freopen("input.txt", "r", stdin); while(scanf("%d%d",&n,&m) != EOF){ clearr(); for(int i =1 ;i <=m;++i){ int x,y; scanf("%d%d",&x,&y); add(x,y); add(y,x); } flag = 0; for(int i = 1;i <=n;++i){ if(col[i] == -1){ if(dfs01(i) == 0){ flag = 1; break; } } } if(flag == 1){ printf("No\n"); continue; } int ans = 0; for(int i = 1;i <= n;++i){ memset(vis,0,sizeof(vis)); if(dfs(i)) ans++; } printf("%d\n",ans/2 ); } }