树上选两点(使最短)树的直径+bfs

题意:

给你一颗树,让你放两个点,放在哪里的时候任意点到某个最近的消防站最远值最小。

思路:

树的直径类题目。

首先我们想两个点会把整棵树分成两个团,所以肯定会在树的某个链上切开。

而且要切一定切在树的直径上,如果不切在直径上,那有一个团的最场距离不就是(直径长度lenth/2了吗)。

所以我们取出直径,枚举切在哪里。

左右两半边的计算方法是一样的,如下图:

我们先算出直径上每个节点的最长距离,因为对于某一个节点,它的分支的长度它到不会超过到直径两端的长度,这样我们就很好算了。

跑两遍:第一次从左到右对左半边的团的直径前缀记录下来,第二次从右到左对右半边的直径后缀记录下来

(注意:1. 对lenth取max,2. 如果直径是偶数如:8,lenth要记为5,mid+1)

最后再跑一遍记录答案就行了。

  1 #define IOS ios_base::sync_with_stdio(0); cin.tie(0);
  2 #include <cstdio>//sprintf islower isupper
  3 #include <cstdlib>//malloc  exit strcat itoa system("cls")
  4 #include <iostream>//pair
  5 #include <fstream>//freopen("C:\Users\13606\Desktop\草稿.txt","r",stdin);
  6 #include <bitset>
  7 //#include <map>
  8 //#include<unordered_map>
  9 #include <vector>
 10 #include <stack>
 11 #include <set>
 12 #include <string.h>//strstr substr
 13 #include <string>
 14 #include <time.h>//srand(((unsigned)time(NULL))); Seed n=rand()%10 - 0~9;
 15 #include <cmath>
 16 #include <deque>
 17 #include <queue>//priority_queue<int, vector<int>, greater<int> > q;//less
 18 #include <vector>//emplace_back
 19 //#include <math.h>
 20 //#include <windows.h>//reverse(a,a+len);// ~ ! ~ ! floor
 21 #include <algorithm>//sort + unique : sz=unique(b+1,b+n+1)-(b+1);+nth_element(first, nth, last, compare)
 22 using namespace std;//next_permutation(a+1,a+1+n);//prev_permutation
 23 #define fo(a,b,c) for(register int a=b;a<=c;++a)
 24 #define fr(a,b,c) for(register int a=b;a>=c;--a)
 25 #define mem(a,b) memset(a,b,sizeof(a))
 26 #define pr printf
 27 #define sc scanf
 28 #define ls rt<<1
 29 #define rs rt<<1|1
 30 typedef long long ll;
 31 void swapp(int &a,int &b);
 32 double fabss(double a);
 33 int maxx(int a,int b);
 34 int minn(int a,int b);
 35 int Del_bit_1(int n);
 36 int lowbit(int n);
 37 int abss(int a);
 38 //const long long INF=(1LL<<60);
 39 const double E=2.718281828;
 40 const double PI=acos(-1.0);
 41 const int inf=(1<<30);
 42 const double ESP=1e-9;
 43 const int mod=(int)1e9+7;
 44 const int N=(int)1e6+10;
 45 
 46 int n;
 47 
 48 bool vis[N];
 49 vector<vector<int> >G(N);
 50 struct node{int now,val;};
 51 void Init()
 52 {
 53     for(int i=1;i<=n;++i)
 54         vis[i]=0;
 55 }
 56 int Val_bfs(node start)
 57 {
 58     int ans=0;
 59     queue<node>q;
 60     q.push(start);
 61     while(!q.empty())
 62     {
 63         node v=q.front();q.pop();
 64         ans=max(ans,v.val);
 65         vis[v.now]=1;
 66         int sz=G[v.now].size();
 67         for(int i=0;i<sz;++i)
 68         {
 69             int to=G[v.now][i];
 70             if(!vis[to])
 71                 q.push({to,v.val+1});
 72         }
 73     }
 74     return ans;
 75 }
 76 
 77 int Start,End;
 78 void queue_dfs1(node start)
 79 {
 80     Init();
 81     int max_=0;
 82     queue<node>q;
 83     q.push(start);
 84     while(!q.empty())
 85     {
 86         node v=q.front();q.pop();
 87         vis[v.now]=1;
 88         if(max_<v.val)max_=v.val,Start=v.now;
 89         int sz=G[v.now].size();
 90         for(int i=0;i<sz;++i)
 91         {
 92             int to=G[v.now][i];
 93             if(!vis[to])
 94                 q.push({to,v.val+1});
 95         }
 96     }
 97 }
 98 int fa[N];
 99 void queue_dfs2()
100 {
101     for(int i=1;i<=n;++i)fa[i]=0;
102     Init();
103     int max_=0;
104     queue<node>q;
105     q.push({Start,1});
106     while(!q.empty())
107     {
108         node v=q.front();q.pop();
109         vis[v.now]=1;
110         if(max_<v.val)max_=v.val,End=v.now;
111         int sz=G[v.now].size();
112         for(int i=0;i<sz;++i)
113         {
114             int to=G[v.now][i];
115             if(!vis[to])
116                 q.push({to,v.val+1}),fa[to]=v.now;
117         }
118     }
119 }
120 int Line[N];
121 int get_line()
122 {
123     Init();
124     int pos=End;
125     int cnt=0;
126     while(fa[pos])
127         Line[++cnt]=pos,vis[Line[cnt]]=1,pos=fa[pos];
128     Line[++cnt]=pos,vis[Line[cnt]]=1;
129     return cnt;
130 }
131 int Val[N];
132 struct mark
133 {
134     int L,p1;
135 }memery[N],memery2[N];
136 void solve(int cnt)
137 {
138     int p1;
139     for(int i=1;i<=cnt;++i)
140         Val[i]=Val_bfs({Line[i],0});
141     memery[0]=memery2[cnt+1]={-1,-1};
142     for(int i=1;i<=cnt-1;++i)
143     {
144         int lenth=(Val[i]+i+1)/2;
145         if((Val[i]+i)%2==0)
146             lenth++;
147         p1=Line[lenth];
148         if(lenth<memery[i-1].L)
149             memery[i]=memery[i-1];
150         else
151             memery[i]={lenth,p1};
152     }
153     int p2;
154     for(int i=cnt;i>=2;--i)
155     {
156         int lenth=(Val[i]+cnt+1-i+1)/2;
157         if((Val[i]+cnt+1-i)%2==0)
158             lenth++;
159         p2=Line[cnt+1-lenth];
160         if(lenth<memery2[i+1].L)
161             memery2[i]=memery2[i+1];
162         else
163             memery2[i]={lenth,p2};
164     }
165     int L=inf,P1,P2;
166     for(int i=1;i<=cnt-1;++i)
167     {
168         if(L>max(memery[i].L,memery2[i+1].L))
169             L=max(memery[i].L,memery2[i+1].L),P1=memery[i].p1,P2=memery2[i+1].p1;
170     }
171     pr("%d %d %d
",L-1,P1,P2);
172 }
173 
174 int main()
175 {
176 //    freopen("C:\Users\13606\Desktop\草稿.txt","r",stdin);
177     int T;
178     sc("%d",&T);
179     while(T--)
180     {
181         sc("%d",&n);
182         for(int i=1;i<=n;++i)
183             G[i].clear();
184         for(int i=1;i<=n-1;++i)
185         {
186             int u,v;
187             sc("%d%d",&u,&v);
188             G[u].push_back(v);
189             G[v].push_back(u);
190         }
191         queue_dfs1({1,1});
192         queue_dfs2();
193         int lenth=get_line();
194         solve(lenth);
195     }
196     return 0;
197 }
198 
199 /**************************************************************************************/
200 
201 int maxx(int a,int b)
202 {
203     return a>b?a:b;
204 }
205 
206 void swapp(int &a,int &b)
207 {
208     a^=b^=a^=b;
209 }
210 
211 int lowbit(int n)
212 {
213     return n&(-n);
214 }
215 
216 int Del_bit_1(int n)
217 {
218     return n&(n-1);
219 }
220 
221 int abss(int a)
222 {
223     return a>0?a:-a;
224 }
225 
226 double fabss(double a)
227 {
228     return a>0?a:-a;
229 }
230 
231 int minn(int a,int b)
232 {
233     return a<b?a:b;
234 }
原文地址:https://www.cnblogs.com/--HPY-7m/p/11457380.html