杭电OJ4607-Park Visit
题意:对于一棵给定的最小生成树,遍历其中固定的顶点数所需要的最短距离
分析:利用树形DP或者两次BFS求出树的直径即可得解
input:
2
13 4
1 2
2 3
2 4
5 4
4 6
6 8
6 9
7 8
9 10
8 11
11 12
11 13
5
7
9
13
output:
4
6
10
18
//Time 842ms
//Memory 5940k
//Date 2015.03.30
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
//#include <cstdio>
using namespace std;
const int MAXN=100001;
int n,m,d;
vector<int> Edge[MAXN];
int dis[MAXN];
void Tree_Diam(int r,int f){ //树形DP
int v;
vector<int>::iterator it;
dis[r]=1;
for(it=Edge[r].begin();it!=Edge[r].end();it++){
v=*it;
if(v!=f){ //排除父节点
Tree_Diam(v,r);
d=max(d,dis[r]+dis[v]);
dis[r]=max(dis[r],dis[v]+1);
}
}
}
int main(){
// freopen("in.txt","r",stdin);//调试
int t,i,j,k,u,v;
scanf("%d",&t);
for(i=0;i<t;i++){
scanf("%d%d",&n,&m);
for(j=1;j<=n;j++)
Edge[j].clear();
for(j=1;j<n;j++){
scanf("%d%d",&u,&v);
Edge[u].push_back(v);
Edge[v].push_back(u);
}
d=0;
memset(dis,0,sizeof(dis));
Tree_Diam(1,0);
for(j=0;j<m;j++){
scanf("%d",&k);
if(k<=d)
printf("%d\n",k-1);
else
printf("%d\n",d-1+(k-d)*2);
}
}
// fclose(stdin);
return 0;
}
//Time 1060ms
//Memory 9096k
//Date 2015.03.30
#include <iostream>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
class Node{
public:
int id;
int level[2];
Node(int i,int l1=0,int l2=0){
id=i;level[0]=l1;level[1]=l2;
}
};
const int MAXN=100001;
int n,m;
vector<Node> Edge[MAXN];
int visit[MAXN];
Node BFS(Node u0,int flag){
Node u(0),v(0),result(0);
vector<Node>::iterator it;
queue<Node> q;
visit[u0.id]=flag;
q.push(u0);
while(!q.empty()){
u=q.front();q.pop();
for(it=Edge[u.id].begin();it!=Edge[u.id].end();it++){
v=*it;
if(visit[v.id]!=flag){
visit[v.id]=flag;
v.level[flag]=u.level[flag]+1;
result=v;
q.push(v);
}
}
}
return result;
}
int Tree_Diam(int r){ //两次BFS
memset(visit,-1,sizeof(visit));
Node u(r,0,0);
Node v1=BFS(u,0);
Node v2=BFS(v1,1);
return v2.level[1];
}
int main(){
int t,i,j,k,u,v,d;
scanf("%d",&t);
for(i=0;i<t;i++){
scanf("%d%d",&n,&m);
for(j=1;j<=n;j++)
Edge[j].clear();
for(j=1;j<n;j++){
scanf("%d%d",&u,&v);
Edge[u].push_back(Node(v));
Edge[v].push_back(Node(u));
}
d=Tree_Diam(1);
for(j=0;j<m;j++){
scanf("%d",&k);
k--;
if(k<=d)
printf("%d\n",k);
else
printf("%d\n",d+(k-d)*2);
}
}
return 0;
}