• 树上选两点(使最短)树的直径+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 }
  • 相关阅读:
    数理统计与Matlab: 第4章 回归分析
    汽车各部位名称详解【图】
    线性代数:第四章 矩 阵1
    曲线救国的就业路线是否合理?
    TortoiseSVN 编辑日志信息报错
    Ironpython及其他托管语言中值类型最好使用构造函数赋值,否则无法赋值的问题
    线性代数:第五章 二次型
    Matlab基础
    技术基层管理者交流QQ群243460070
    MATLAB软件基础
  • 原文地址:https://www.cnblogs.com/--HPY-7m/p/11457380.html
Copyright © 2020-2023  润新知