F.Three pahs on a tree

 思路

  两次bfs找出树的直径并处理出端点离树上各叶子节点的距离,在直径上找一点的子树叶子p3,使得dis(p1,p2) + dis(p2,p3) + dis(p1,p3)最大

  易知上式是路径实长的两倍

  1 #include <bits/stdc++.h>
  2 #define dbg(x) cout << #x << "=" << x << endl
  3 #define eps 1e-8
  4 #define pi acos(-1.0)
  5 
  6 using namespace std;
  7 typedef long long LL;
  8 
  9 template<class T>inline void read(T &res)
 10 {
 11     char c;T flag=1;
 12     while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
 13     while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
 14 }
 15 
 16 namespace _buff {
 17     const size_t BUFF = 1 << 19;
 18     char ibuf[BUFF], *ib = ibuf, *ie = ibuf;
 19     char getc() {
 20         if (ib == ie) {
 21             ib = ibuf;
 22             ie = ibuf + fread(ibuf, 1, BUFF, stdin);
 23         }
 24         return ib == ie ? -1 : *ib++;
 25     }
 26 }
 27 
 28 int qread() {
 29     using namespace _buff;
 30     int ret = 0;
 31     bool pos = true;
 32     char c = getc();
 33     for (; (c < '0' || c > '9') && c != '-'; c = getc()) {
 34         assert(~c);
 35     }
 36     if (c == '-') {
 37         pos = false;
 38         c = getc();
 39     }
 40     for (; c >= '0' && c <= '9'; c = getc()) {
 41         ret = (ret << 3) + (ret << 1) + (c ^ 48);
 42     }
 43     return pos ? ret : -ret;
 44 }
 45 
 46 const int maxn = 2e5 + 7;
 47 
 48 int head[maxn << 1], edge[maxn << 1], nxt[maxn << 1];
 49 int w[maxn << 1];
 50 int vis[maxn];
 51 int dis[maxn];
 52 
 53 int n, cnt;
 54 
 55 void BuildGraph(int u, int v, int c) {
 56     cnt++;
 57     edge[cnt] = v;
 58     nxt[cnt] = head[u];
 59     w[cnt] = c;
 60     head[u] = cnt;
 61 }
 62 
 63 int bfs(int x) {
 64     memset(vis, 0, sizeof(vis));
 65     memset(dis, 0, sizeof(dis));
 66     int pos = 0;
 67     queue <int> q;
 68     q.push(x);
 69     vis[x] = 1;
 70     int u;
 71     while(!q.empty()) {
 72         u = q.front();
 73         //dbg(u);
 74         q.pop();
 75         for (int i = head[u]; i; i = nxt[i]) {
 76             int v = edge[i];
 77             int d = w[i];
 78             if(vis[v])
 79                 continue;
 80             else {
 81                 dis[v] = dis[u] + d;
 82                 vis[u] = 1;
 83                 if(dis[v] > dis[pos]) {
 84                     pos = v;
 85                 }
 86                 q.push(v);
 87             }
 88         }
 89     }
 90     return pos;
 91 }
 92 
 93 int d1[maxn], d2[maxn];
 94 
 95 int main()
 96 {
 97     read(n);
 98     int a, b;
 99     for ( int i = 1; i < n; ++i ) {
100         read(a);
101         read(b);
102         BuildGraph(a, b, 1);
103         BuildGraph(b, a, 1);
104     }
105     int p1, p2;
106     p1 = bfs(1);
107     p2 = bfs(p1);
108     for ( int i = 1; i <= n; ++i ) {
109         d1[i] = dis[i];     
110     }   
111     int p3 = bfs(p2);
112     for ( int i = 1; i <= n; ++i ) {
113         d2[i] = dis[i];
114     }
115     int p4 = 0;
116     for ( int i = 1; i <= n; ++i ) {
117         if(d1[i] + d2[i] > d1[p4] + d2[p4] && i != p1 && i != p2) {
118             p4 = i;
119         }
120     }
121     int ans = d1[p4]+d2[p4]+d1[p2];
122     //dbg(ans);
123     printf("%d
",ans / 2);
124     printf("%d %d %d
",p1,p2,p4);
125     return 0;
126 }
View Code
原文地址:https://www.cnblogs.com/orangeko/p/12334158.html