Test instructions
Find two points on the tree to minimize the maximum distance from other points to these two points at random
Ideas:
Maximum minimum think of two points on the basis of two to determine whether this maximum value is possible
How to determine the problem is how to choose the two points of the problem is very obvious we have to deal with the diameter (otherwise the longest is the diameter) then since there is a value to determine X is best to choose the distance between the two ends of the point distance of X is good
The number of points on the diameter up to n is the complexity of the two points O (NLOGN) to solve
Code:
#include <cstdio> #include <iostream> #include <cstring> #include <string> #include < algorithm> #include <map> #include <set> #include <vector> #include <queue> #include < cstdlib> #include <ctime> #include <cmath>using namespace std;typedef long long LL; #define N 200010int t, N; struct Edge {int V, next;} Ed[n * 2];int head[n], Tot;int dis[n], Pre[n];int route[n], m;void Add (int u, int v) {ED[TOT].V = V;ed[tot].next = Head[u];head[u] = tot++;} int qu[n];int BFS (int u) {int L = 0, r = 1;int pos = u, val = 0;dis[u] = 0;qu[0] = U;while (L < r) {u = qu[l++];for (in t i = head[u]; ~i; i = ed[i].next) {int v = ed[i].v;if (dis[v] = =-1) {Pre[v] = u;dis[v] = Dis[u] + 1;qu[r++] = v;if (Dis[v] > val) {val = DIS[V];p os = v;}}} return POS;} int Flag[n];bool Yes (int ans) {memset (flag, 0, sizeof (flag)), memset (Dis,-1, sizeof (DIS)), BFS (Route[ans]); for (int i = 1; I <= N; i++) {if (Dis[i] <= ans) flag[i] = 1;} memset (Dis,-1, sizeof (DIS)); BFS (routE[m-1-ans]); for (int i = 1; I <= n; i++) {if (Dis[i] <= ans) flag[i] = 1;} for (int i = 1; I <= n; i++) {if (!flag[i]) return false;} return true;} int main () {int i, U, v;scanf ("%d", &t), while (t--) {tot = 0;memset (head,-1, sizeof (head)), scanf ("%d", &n); for (i = 1; I < n; i++) {scanf ("%d%d", &u, &v); Add (U, v); Add (v, u);} memset (Dis,-1, sizeof (DIS)), u = BFS (1), memset (Dis,-1, sizeof (DIS)), memset (pre,-1, sizeof (PRE)), V = BFS (u), M = 0;while ( V! =-1) {route[m++] = V;v = Pre[v];} int L = 0, R = m-1, Mid, Ans[3];while (L <= r) {mid = (L + R)/2;if (yes (mid)) {Ans[0] = mid;ans[1] = Route[mid];ans [2] = route[m-1-Mid];if (ans[1] = ans[2]) {for (i = 0; i < m; i++) {if (Route[i]! = Ans[1]) {ans[2] = Route[i];bre ak;}}} R = mid-1;} Elsel = mid + 1;} printf ("%d%d%d\n", Ans[0], ans[1], ans[2]);} return 0;}
ZOJ 3820 Building Fire Stations