随笔 - 97, 文章 - 22, 评论 - 81, 引用 - 0
数据加载中……

Pku 1632 Vase Collection (Dfs)

问题描述:
给定一些关系,是个二分图,要求它的最大完美匹配。
解题思路:
枚举左边的点,对任意一个点枚举它的边子集,再在枚举到的边子集的右边点集中以相同方式枚举,最后形成左右两边均为K的点,检测是否为完全二分图即可。

代码如下:
#include <iostream>
#include 
<vector>
using namespace std;

int t;
int n, i;

vector 
< int > lvec[40], rvec[40];
int l, r, dep;
int bo[40], Max;

struct Stack
{
    
int a[100];
    
int top;
}
Left, Right;

int map[40][40];


//检查给定图是否是K-完美匹配图(这里K == Left.top)
int Process()
{
    
int i, j;
    
//Stack Left
    
//Stack Right
    
//检查两个栈中是否有完全边,即K*K条边

    
for(i = 0; i < Left.top; i++)
    
{
        
for(j = 0; j < Right.top; j++)
        
{
            
if(!map[ Right.a[j] ][ Left.a[i] ])
                
return 0;
        }

    }


    
return 1;
}



//对右边的第一个被左边点枚举到的点进行枚举,枚举它的边子集
int rdfs(int u, int index)
{
    
int i, size = rvec[u].size();

    
if(size < Left.top)
        
return 0;

    
if(Right.top > Left.top)
        
return 0;

    
if(Left.top == Right.top)
    
{
        
if( Process() )
            
return 1;
    }


    
for(i = index; i < size; i++){
        Right.a[ Right.top
++ ] = rvec[u][i];
        
if( rdfs(u, i+1) )
            
return 1;
        Right.top 
--;
    }

    
return 0;
}


//左边任选一个点枚举他的边子集

void ldfs(int u, int index)
{
    
int i, size = lvec[u].size();

    
if(Left.top > 10)
        
return ;

    Right.top 
= 0;


    
if(Left.top > Max && rdfs(Left.a[0], 0) )
    
{
        
if(Left.top > Max)
            Max 
=  Left.top;
    }


    
for(i = index; i < size; i++){
        Left.a[ Left.top
++ ] = lvec[u][i];
        ldfs(u, i
+1);
        Left.top 
--;
    }

}


int main()
{
    
int i, j;
    scanf(
"%d"&t);

    
while(t--)
    
{
        Max 
= 0;
        scanf(
"%d"&n);

        memset(map, 
0sizeof(map));

        
for(i = 1; i <= 36; i++)
        
{
            lvec[i].clear();
            rvec[i].clear();
        }


        memset( bo, 
0sizeof(bo) );

        
for(i = 0; i < n; i++)
        
{
            scanf(
"%d %d"&l, &r);
            map[l][r] 
= 1;
            bo[ l ] 
= 1;
        }


        
for(i = 1; i <= 36; i++){

            
for(j = 1; j <= 36; j++){

                
if(map[i][j])
                
{
                    lvec[i].push_back( j );
                    rvec[j].push_back( i );
                }

            }

        }


        
for(i = 1; i <= 36; i++)
        
{
            
if(bo[i]){
                Left.top 
= 0;
                ldfs(i, 
0);
            }

        }

        printf(
"%d\n", Max);
    }

}

posted on 2009-02-15 21:15 英雄哪里出来 阅读(390) 评论(0)  编辑 收藏 引用 所属分类: ACM


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理