树上最短路

题目:

  给出一棵树进行如下操作:

          (1)把某个点上染黑

          (2)询问某个点,到最近黑点的距离。

          开始时,把‘1’点染黑。

  • 10% N,M ≤ 10
  • 40% N,M ≤ 100
  • 100% N ≤ 2 × 10 5 ,M ≤ 10 5

思路:(搜索的思路)

  每加入一个点就更新,最短路。记录答案。

一个剪枝:

  当你要更新的值大于或等于它原来的值时,就不用向后更新了。(因为后面的点肯定离另一个点比这个点近)

具体代码:

  bfs

  

#include<iostream>
#include<cstdio>
#include<math.h>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m,q[99999999];
int h[200009],next[400009],to[400009],cnt,ans[200009];
void bfs(int x)
{
    int l=0,r=1;
    int now,t;
    q[x]=x;ans[x]=1;
    while(l<=r)
    {
        now=q[++l];
        for(int i=h[x];i;i=next[i])
        {    t=to[i];        
            if(ans[now]+1<ans[t])
            {                
                ans[t]=ans[now]+1;
                q[++r]=t;
            }
        }
    }
}
int main()
{    
    freopen("travel.in","r",stdin);
    freopen("travel.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1,x,y;i<n;i++)
    {
        scanf("%d%d",&x,&y);
        to[++cnt]=y,next[cnt]=h[x],h[x]=cnt;
        to[++cnt]=x,next[cnt]=h[y],h[y]=cnt;        
    }
    memset(ans,0x7f,sizeof(ans));
    bfs(1);
    for(int i=1,A,B;i<=m;i++)
    {
        scanf("%d",&A);
        if(A==2)
        {
            scanf("%d",&B);
            printf("%d\n",ans[B]);
        }
        if(A==1)
        {
            scanf("%d",&B);
            bfs(B);
        }
    }
    return 0;
} 

  dfs

#include<iostream>
#include<cstdio>
#include<math.h>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m;
int h[200009],next[400009],to[400009],cnt,ans[200009],last;
void dfs(int x,int last,int y)
{
    ans[x]=y;
    int t;
    for(int i=h[x];i;i=next[i])
    {    t=to[i];
        if(t!=last&&y+1<ans[t])
            dfs(t,x,y+1);    
    }
    return;
}
int main()
{    
    freopen("cicada.in","r",stdin);
    freopen("cicada.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1,x,y;i<n;i++)
    {
        scanf("%d%d",&x,&y);
        to[++cnt]=y,next[cnt]=h[x],h[x]=cnt;
        to[++cnt]=x,next[cnt]=h[y],h[y]=cnt;        
    }    
    memset(ans,0x7f,sizeof(ans)); 
    dfs(1,1,0);
    for(int i=1,A,B;i<=m;i++)
    {
        scanf("%d",&A);
        if(A==2)
        {
            scanf("%d",&B);
            printf("%d\n",ans[B]);
        }
        if(A==1)
        {
            scanf("%d",&B);
            dfs(B,B,0);
        }
    }
    return 0;
} 

 

posted @ 2017-07-25 11:09  浪矢-CL  阅读(461)  评论(0编辑  收藏  举报