终于弄懂了..
对上部点逐个寻找连接,找到则连接数+1:
对于一上部点u,若能找到一下部点v,u与v匹配,且v未被连接,则连接u与v,连接数+1
对于一上部点u,若能找到一下部点v,u与v匹配
而v已与u'连接
若u'能找到另一可连接的匹配v'.则可以通过连接u-v,u'-v'使连接数+1
红色部分是一个递归过程,一直到能找到一个未连接的下部点为止,修改连接,返回1.
或找不到这样一个点,返回0
--------------------------------------------------------代码----------------------------------------------------------------
- const int vn=100;
- int un; //上部的结点数
- int dn; //下部的结点数
- char gra[vn][vn]; //gra[i][j]表示上部图中的点i与下部图中的点j是否匹配
- char check[vn]; //记录下部图中的点有没被扫描过
- int du[vn]; //du[i]表示与下部结点i连接的上部的点
- int find(int u) //寻找一下部点v,v可以与u连接.
- {
- int d;
- for(d=0;d< dn;d++)
- {
- if(gra[u][d]==1&&check[d]==0) //若两点匹配,且下部的d点未被扫描
- {
- check[d]=1;
- if(du[d]==-1||find(du[d])==1) //若d点未被连接,或与d点连接的上部点可以找到一与之匹
- { //配,而未被连接的下部点(寻找可增广路)
- du[d]=u; //修改与此下部点连接的上部点的索引
- return 1;
- }
- }
- }
- return 0;
- }
- int match()
- {
- int i;
- int sum=0;
- memset(du,-1,sizeof(du));
- for(i=0;i< un;i++)
- {
- memset(check,0,sizeof(check));
- if(find(i)==1)
- sum++;
- }
- return sum;
- }
- int main()
- {
- int i,j;
- scanf("%d %d",&un,&dn);
- for(i=0;i< un;i++)
- for(j=0;j< dn;j++)
- scanf("%d",&gra[i][j]);
- printf("%d/n",match());
- return 0;
- }