百度2011校招笔试算法题一

1.问题描述

有一个单入口,单出口的有向无环图。给出一个算法,在已有结点之间插入若干结点,使得从入口结点到出口结点经过的任意路径长度一致,详细描述你的算法思路,并分析其时间复杂度和空间复杂度。

 

2.算法思路

首先深度遍历,计算出入口到出口的最长路径,然后重新深度遍历,遍历到出口节点之前计算此路径长度,如果计算出小于最长路径则插入节点,使这个路径等于最长路径。

 

3.算法实现:(仅供参考)

struct Edge{
    VPoint *dest; 
    Edge *next;
}


struct VPoint{
    int id;
    int weight;
    Edge *adj;
}

int longestDeep(VPoint *v , int visited[])
{
    int max=MIN,temp;
    VPoint *vp;

    if(v==NULL)  return 0;
    
    visited[v->id]=1
    for(Edge *ep=v->adj;;ep!=NULL;ep=ep->next)
    {  
       vp=ep->dest;
       if(visited[vp->id]==0)
       {
           temp=longestDeep(vp);
           if(temp>max)
               max=temp;
       }
    }
    return max + 1;
}

int deepmax=longestDeep(v,visited);                //O(n+e)   O(1)


Edge* insert(Edge *ep)
{
     VPoint *newp = (VPoint*)malloc(VPoint);
     Edge *newe = (Edge *)malloc(Edge);

     init(newp);                              //初始化新节点
     newp->adj=newe;
     newe->next=NULL;                         //新插结点的后续边的个数 必为一个
     newe->dest=ep->dest;
     ep->dest=newp;

     return newe;
}



void extendPoint(VPoint *v, int visited[],int deep)   //  {
     if(v==NULL)  return;
     
     visited[v->id]=1
     for(Edge *ep=v->adj;ep!=NULL;ep=ep->next)
     {  
        vp=ep->dest;
        if(visited[vp->id]==0)
        {
            deep++;
            if(vp->id==ENDID && deep+1 < deepmax)            //?
            {
                  int num=deepmax - (deep+1),i;
                  for(i=1;i<=num;i++)
                           ep = insert(ep);  
                  return;
             }
            extendPoint(vp,visited,deep);
        }
     }
}
//时间复杂度O(n+e) 空间复杂度O(1)

 

 

posted on 2012-07-16 17:48  as_  阅读(1404)  评论(0编辑  收藏  举报

导航