来源:互联网 发布:java 值传递 引用传递 编辑:程序博客网 时间:2024/04/30 12:24

题目描述
每个人物的黑化值是距离他最近的一只蝉到他的距离

n个点构成一棵树
初始时1号节点上有一只蝉

m个操作
1.在x号节点上放一只蝉
2.求x号节点上人物的黑化值

正解据说是树链剖分
总之我是不会
那就
搜索呗
非常普通的搜索

BFS 80

#include<iostream>#include<cstring>#include<algorithm>#include<cstdio>#include<cmath>#include<queue>#include<vector>#include<climits>#include<string>#include<cstdlib>#include<ctime>#define MOD 1000000007#define LL long longusing namespace std;int cnt,num[400005],nxt[400005],head[200005],point[400005],father[400005],blood[200005],n,m;void add(int p1,int p2){    cnt++;    num[cnt]=p2;    nxt[cnt]=head[p1];    head[p1]=cnt;}void west(int p){       int h=1,t=1,x,i;    point[h]=p;    father[h]=0;    blood[point[h]]=0;    while(h<=t)    {        x=point[h];        for(i=head[x];i;i=nxt[i])            if(num[i]!=father[h]&&blood[num[i]])            {                t++;                father[t]=x;                point[t]=num[i];                blood[point[t]]=min(blood[point[t]],blood[point[h]]+1);            }        h++;    }}int main(){    int i,x,y,opt;    scanf("%d%d",&n,&m);    memset(blood,127,sizeof(blood));    for(i=1;i<n;i++)    {        scanf("%d%d",&x,&y);        add(x,y);        add(y,x);    }    west(1);    for(i=1;i<=m;i++)    {        scanf("%d%d",&opt,&x);        if(opt==1) west(x);        if(opt==2) printf("%d\n",blood[x]);    }    return 0;}

然后
其实再加一个优化
就能够再多过一个点
就是说
不只搜到蝉的时候停止
在搜到实际的黑化值与距离一致的点时

由这个点延伸出去的点
黑化值没有任何变化
直接停掉

有关这个优化和DFS
之后再补上