HDU 1689 (BFS+剪枝)

题目意思是检测最小奇数环 并输出结果

 

对于该类题目 分析了下复杂度 可以对各个点进行一一枚举 对于每次的枚举 记录访问到该点时的深度 当下一次访问时只要将当前深度加上访问到该点的深度就能计算出总共所用去的点数 使用2个队列  以形成逐层遍历(保证了路径的不重复) 感觉很不错 每次枚举计算出的最小值可以作为下一次的阀值 从而达到了缩小规模的目的

 

OK 下面是代码啦....

 

 

#include  < iostream >
#include 
< queue >
using   namespace  std;
typedef 
struct  
{
    
long  next;
    
long  v;
}Edge;
long  dp[ 1010 ];
long  p[ 1010 ];
Edge e[
40010 ];
long  N,M;
bool  vist[ 1010 ];
typedef 
struct   
{
    
long  v;
}Node;
queue
< Node >  q;
queue
< Node >  save;
inline 
void  BFS()
{

    
    
long  i;
    
long  res = INT_MAX;

    
for  (i = 1 ;i <= N; ++ i)
    {
        
while  ( ! q.empty())
        {
            q.pop();
        }

        memset(vist,
0 , sizeof (vist));
        
        Node st;
        st.v
= i;
        dp[i]
= 0 ;
        q.push(st);
        vist[i]
= true ;

        
long  len = 0 ;

        
while  ( ! q.empty() &&++ len < res)
        {
            
while  ( ! save.empty())
            {
                save.pop();
            }

            
while ( ! q.empty()) // 逐层扩展
            {
                Node t
= q.front();
                q.pop();
                
long  j;
                
for  (j = p[t.v];j !=- 1 ;j = e[j].next)
                {
                    
long  v = e[j].v;
                    
if  (vist[v])
                    {
                        
long  now = dp[v] + len;
                        
if  (now < res && now & 1 )
                        {
                            res
= now;
                        }
                    }
                    
else
                    {
                        Node tt;
                        tt.v
= v;
                        save.push(tt);
                        vist[v]
= true ;
                        dp[v]
= len;
                    }
                }
            }

            
while  ( ! save.empty())
            {
                q.push(save.front());
                save.pop();
            }
        }
    }

    
if  (res == INT_MAX)
    {
        puts(
" Poor JYY. " );
    }
    
else
    {
        printf(
" JYY has to use %ld balls.\n " ,res);
    }
}

int  main()
{
    
long  T;
    scanf(
" %ld " , & T);
    
long  b = 1 ;
    
while  (T -- )
    {
        memset(p,
- 1 , sizeof (p));        
        scanf(
" %ld %ld " , & N, & M);
        
long  eid = 0 ;
        
while  (M -- )
        {
            
long  from,to;
            scanf(
" %ld %ld " , & from, & to);
            
            e[eid].next
= p[from];
            e[eid].v
= to;
            p[from]
= eid ++ ;
            swap(from,to);
            e[eid].next
= p[from];
            e[eid].v
= to;
            p[from]
= eid ++ ;
            
        }
        printf(
" Case %ld:  " ,b);
        BFS();
        
++ b;
    }
    
return   0 ;
}

 

 

 

转载于:https://www.cnblogs.com/zhuangli/archive/2008/09/06/1285516.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值