10W个点的一棵树,边权为1
求访问K个点要走过的最小路程
BFS求出一条最长路以后,我们可以YY出其他的边都要重复走两次
树上的最长路可以从任意一点开始BFS求出这点的最大距离,再把终点设置为起点再做一次BFS
所以就判断K和最长路间的距离就行了 O(n) 算法
1 #include <set> 2 #include <map> 3 #include <list> 4 #include <cmath> 5 #include <ctime> 6 #include <deque> 7 #include <queue> 8 #include <stack> 9 #include <bitset> 10 #include <cstdio> 11 #include <string> 12 #include <vector> 13 #include <cassert> 14 #include <cstdlib> 15 #include <cstring> 16 #include <sstream> 17 #include <fstream> 18 #include <numeric> 19 #include <iomanip> 20 #include <iostream> 21 #include <algorithm> 22 #include <functional> 23 using namespace std; 24 //typedef long long LL; 25 //typedef unsigned long long ULL; 26 // typedef __int64 LL; 27 // typedef unisigned __int64 ULL; 28 #define EPS 1e-8 29 #define MAXN 100005 30 #define MAXE 200005 31 #define INF 0x3f3f3f3f 32 #define PI acos(-1.0) 33 #define MOD 1000000007 34 #define max(a,b) ((a) > (b) ? (a) : (b)) 35 #define min(a,b) ((a) < (b) ? (a) : (b)) 36 #define max3(a,b,c) (max(max(a,b),c)) 37 #define min3(a,b,c) (min(min(a,b),c)) 38 #define mabs(a) (((a) < 0) ? (-a) : (a)) 39 #define YES cout<<"YES"<<endl; 40 #define L(t) (t << 1) 41 #define R(t) (t << 1 | 1) 42 #define Mid(a,b) ((a+b)>>1) 43 #define lowbit(a) (a&-a) 44 #define FOR(a,b,c) for(int a = b; a < c; a++) 45 #define FOR2(a,b,c) for(int a = b; a <= c; a++) 46 #define LOOP(a,b) for(int lop = a; lop < b; lop++) 47 #define LOOP2(a,b) for(int lop = a; lop <= b; lop++) 48 //int gcd(int a,int b){ return b?gcd(b,a%b):a; } 49 //int lcm(int a,int b){ return a*b/gcd(a,b); } 50 struct Edge 51 { 52 int u,v,w; // st,ed,value 53 int next; 54 }edge[MAXE]; 55 struct Point 56 { 57 int p; 58 int dis; 59 Point(int a,int b) 60 { 61 p = a; 62 dis = b; 63 } 64 }; 65 int head[MAXN]; 66 bool vis[MAXN]; 67 int cnt ; // num of edge 68 int n ; // num of point 69 int m ; 70 void add(Edge x) 71 { 72 edge[cnt].u = x.u; 73 edge[cnt].v = x.v; 74 edge[cnt].w = x.w; 75 edge[cnt].next = head[x.u]; 76 head[x.u] = cnt++; 77 edge[cnt].v = x.u; 78 edge[cnt].u = x.v; 79 edge[cnt].w = x.w; 80 edge[cnt].next = head[x.v]; 81 head[x.v] = cnt++; 82 } 83 int endp; 84 int bfs(int s) 85 { 86 int dis = -INF; 87 queue<Point> q; 88 Point p(s,0); 89 q.push(p); 90 vis[s] = true; 91 while(!q.empty()) 92 { 93 int u = q.front().p; 94 int d = q.front().dis; 95 if(d > dis) 96 { 97 dis = max(dis,d); 98 endp = u; 99 } 100 for(int i = head[u]; i != -1; i = edge[i].next) 101 { 102 if(!vis[edge[i].v]) 103 { 104 q.push(Point(edge[i].v,d+1)); 105 vis[edge[i].v] = true; 106 } 107 } 108 q.pop(); 109 } 110 return dis; 111 } 112 int main() 113 { 114 // freopen("in.txt","r",stdin); 115 // freopen("out.txt","w",stdout); 116 // std::ios::sync_with_stdio(false); 117 int t; 118 scanf("%d",&t); 119 while(t--) 120 { 121 cnt = 0; 122 scanf("%d%d",&n,&m); 123 memset(vis,0,sizeof(vis)); 124 memset(edge,0,sizeof(edge)); 125 memset(head,-1,sizeof(head)); 126 for(int i = 0 ; i < n-1 ; i++) 127 { 128 int a,b; 129 scanf("%d%d",&a,&b); 130 Edge E; 131 E.u = a; 132 E.v = b; 133 add(E); 134 } 135 int dis1 = bfs(1); 136 memset(vis,0,sizeof(vis)); 137 int dis = bfs(endp); 138 for(int i = 0 ; i < m ; i++) 139 { 140 int k; 141 scanf("%d",&k); 142 if(k-1 <= dis) printf("%d ",k-1); 143 else printf("%d ",dis+2*(k-dis-1)); 144 } 145 } 146 return 0; 147 }