题目 http://acm.hdu.edu.cn/showproblem.php?pid=2444
关键这个问题你要知道什么是二分 就是一条直线相连的二个点 一个在集合A 另一个在B 所以你首先判断是不是二分 可以用二种颜色来区别哦 。
求最大匹配 你可以把A B 集合看成是一个集合哦 然后来计算这个集合的最大匹配
#include <iostream> using namespace std; const int M=201; bool g[M][M]; //图 bool visit[M]; //标记 bool flag; int link[M]; //标记那个与那个相连 int c[M]; //表示颜色,0表示没访问,1表示黑色,-1表示白色 int n,k; void dfs(int i,int color)//染色法判断是否是二分图 { for(int j=1;j<=n;j++) { if(g[i][j]) { if(c[j]==0) { c[j]=-color; dfs(j,-color); } else if(c[j]==color) { flag=false; return; } if(flag==false) return ; } } } bool check() { flag=true; memset(c,0,sizeof(c)); c[1]=1; //设一号点是黑色,与它相邻的都染成白色 dfs(1,1); //从1号点开始 return flag; } bool find(int i) //寻找增广路径 { int j; for(j=1;j<=n;j++) { if(g[i][j] && !visit[j]) { visit[j]=true; if(link[j]==0 || find(link[j])) { link[j]=i; return true; } } } return false; } int main() { int i,j,res; while(cin>>n>>k) { memset(g,0,sizeof(g)); memset(link,0,sizeof(link)); res=0; while(k--) { cin>>i>>j; g[i][j]=g[j][i]=true; } if(!check()) { cout<<"No\n"; continue; } //求最大匹配哦 for(i=1;i<=n;i++) //以x集合为准找了一遍,又以y集合为准找了一遍,匹配数量增倍。[x]+[y]=n { memset(visit,0,sizeof(visit)); if(find(i)) res++; } cout<<res/2<<endl; } return 0; }