題意:
一些學生之間是朋友關係(關係不能傳遞)...現在要將一堆學生分成兩堆,使得在同一堆的學生之間沒有朋友關係..如果能成功..再問若把每對朋友關到小黑屋..最多能關多少對
題解:
這題就體現了二分圖這個模型的基本條件...分為兩個部分..內部沒有邊.邊只在兩個部分間...第一問..就是判斷二分圖..用染色的方法就好..下一問就是裸的匈牙利了...
Program:
#include<iostream>#include<stdio.h>#include<algorithm>#include<cmath>#include<stack>#include<string.h>#include<queue>#define ll long long#define esp 1e-5#define MAXN 202#define MAXM 50000000#define oo 100000007using namespace std; int color[MAXN],match[MAXN];bool used[MAXN];vector<int> T[MAXN];bool PutColor(int x,int tp){ if (color[x]==1-tp) return false; if (color[x]==tp) return true; color[x]=tp; for (int i=0;i<T[x].size();i++) if (!PutColor(T[x][i],!tp)) return false; return true;}bool judge(int n){ memset(color,-1,sizeof(color)); for (int i=1;i<=n;i++) if (color[i]==-1 && !PutColor(i,0)) return false; return true;}bool dfs(int x){ for(int i=0;i<T[x].size();i++) { int y=T[x][i]; if (used[y]) continue; used[y]=true; if (!match[y] || dfs(match[y])) { match[y]=x;; return true; } } return false;}int getmax(int n){ int sum=0; memset(match,0,sizeof(match)); for (int i=1;i<=n;i++) if (color[i]==1) { memset(used,false,sizeof(used)); sum+=dfs(i); } return sum;}int main() { int i,n,m; while (~scanf("%d%d",&n,&m)) { for (i=1;i<=n;i++) T[i].clear(); while (m--) { int x,y; scanf("%d%d",&x,&y); T[x].push_back(y),T[y].push_back(x); } if (!judge(n)) { printf("No\n"); continue; } printf("%d\n",getmax(n)); } return 0; }