hdu4607

来源:互联网 发布:中国航信集团知乎 编辑:程序博客网 时间:2024/05/12 11:21

题目大意:

有n个点,这些点之间存在n-1条路,每条道之间的距离是1,现在问你要浏览m个点至少得走多少路?


啥也不说了,看这张图你就应该明白了吧!

/**   找到一条直路,然后再考虑岔路,发现每条岔路都需要先走出去,然后再回到直路上的点接着走到尾   得到当需要访问的景点数目小于等于直路上的景点的和数目的时候不需要走岔路,大于的时候每多走一个景点就得多计算一个返程   所以本题的关键就是找到那条最长的直路了!**/#include<stdio.h>#include<Vector>#include<queue>#include<string.h>#define N 100009using namespace std;struct node{   int pos;   int dis;}point;vector <int> mp[N];bool vi[N];int n;node bfs(node st){    queue<node>q;    q.push(st);    node temp;    memset(vi,0,sizeof(bool)*(n+2));    vi[st.pos]=1;    int i;    while(!q.empty()){        st=q.front();q.pop();        for(i=0;i<mp[st.pos].size();i++){                temp.pos=mp[st.pos][i];                if(vi[temp.pos])                       continue;                temp.dis=st.dis+1;                vi[temp.pos]=1;                q.push(temp);        }    }    return st;}int main(){    int t,q,a,b,i,j;    scanf("%d",&t);    while(t--){            scanf("%d%d",&n,&q);            for(i=0;i<=n;i++)               mp[i].clear();            for(i=1;i<n;i++){                scanf("%d%d",&a,&b);                mp[a].push_back(b);                mp[b].push_back(a);            }            node start;            start.pos=1;            start.dis=0;            node ans=bfs(start);//找到尾            ans.dis=0;            ans=bfs(ans);//找到首            b=ans.dis;            for(i=0;i<q;i++){                    scanf("%d",&a);                    if((a-1)<=b)                        printf("%d\n",a-1);                    else{                        a=(2*a-b-2);                        printf("%d\n",a);                    }            }      }}


0 0