zoukankan      html  css  js  c++  java
  • zoj3820 Building Fire Stations 树的中心

    题意:n个点的树,给出n-1条边,每条边长都是1,两个点建立防火站,使得其他点到防火站的最远距离最短。

    思路:比赛的时候和队友一开始想是把这两个点拎起来,使得层数最少,有点像是树的中心,于是就猜测是将树的中心找到后,将两棵左右子树分别求树的中心,这两棵树的中心就是答案,but另外一个队友又说了个反例,脑子也不清醒,以为还有没考虑到的,比赛也没A,赛后一想就是最初的猜想,回来之后写了写,报栈了,数据范围太大,真不想改,今天改了改,改成bfs又tle了,囧囧的,把memset和memcpy都改成循环AC了,代码写的很不优雅。

    如果最一开始树的直径是偶数,即1-2-3-4,则拆成1-2和3-4。

    如果最一开始树的直径是奇数,即1-2-3-4-5,则拆成1-2-3和3-4-5。

    丑丑的代码:

      1 /*===============================================================
      2 *   Copyright (C) 2014 All rights reserved.
      3 *
      4 *   File Name: zoj3172.cpp
      5 *   Author:sunshine
      6 *   Created Time: 2014年10月14日
      7 *
      8 ================================================================*/
      9 #include <map>
     10 #include <queue>
     11 #include <math.h>
     12 #include <stdio.h>
     13 #include <string.h>
     14 #include <iostream>
     15 #include <algorithm>
     16 
     17 using namespace std;
     18 
     19 #define N 500010
     20 
     21 int head[N];
     22 int edgeNum;
     23 struct Edge{
     24     int v,to;
     25 }edge[N];
     26 int edge_u_v[N][2];
     27 
     28 void addedge(int a,int b){
     29     edge[edgeNum].v = b;
     30     edge[edgeNum].to = head[a];
     31     head[a] = edgeNum ++;
     32 }
     33 
     34 int vis[N],depth,ind;
     35 int t_vis[N],father[N];
     36 int stack[N];
     37 void bfs(int u){
     38     vis[u] = 1;
     39     queue<int>que;
     40     que.push(u);
     41     while(!que.empty()){
     42         int tmp = que.front();
     43         que.pop();
     44         if(vis[tmp] >= depth){
     45             depth = vis[tmp];
     46             ind = tmp;
     47         }
     48         for(int i = head[tmp];i != -1;i = edge[i].to){
     49             int v = edge[i].v;
     50             if(vis[v] == 0){
     51                 vis[v] = vis[tmp] + 1;
     52                 father[v] = tmp;
     53                 que.push(v);
     54             }
     55         }
     56     }
     57     int tmp = ind;
     58     for(int i = 0;i < depth;i ++){
     59         stack[i] = tmp;
     60         tmp = father[tmp];
     61     }
     62     return ;
     63 }
     64 
     65 
     66 void init(int n){
     67     edgeNum = 0;
     68     //memset(head,-1,sizeof(head));
     69     //memset(vis,0,sizeof(vis));
     70     //memset(father,-1,sizeof(father));
     71     for(int i = 0;i <= n;i ++) {
     72         head[i] = -1;
     73         vis[i] = 0;
     74         father[i] = -1;
     75     }
     76 }
     77 
     78 int main(){
     79     int t;
     80     int n;
     81     int u,v;
     82     //freopen("data.in","r",stdin);
     83     //freopen("data.out","w",stdout);
     84     scanf("%d",&t);
     85     while(t --){
     86         scanf("%d",&n);
     87 
     88         init(n);
     89         for(int i = 0;i < n - 1;i ++){
     90             scanf("%d%d",&u,&v);
     91             edge_u_v[i][0] = u;
     92             edge_u_v[i][1] = v;
     93             addedge(u,v);
     94             addedge(v,u);
     95         }
     96 
     97         depth = 1;
     98         bfs(1);
     99         for(int i = 0;i <= n;i ++) vis[i] = 0;
    100         bfs(ind);
    101 
    102         int ans_one,ans_two;
    103         int depth_one,depth_two;
    104         //left graph
    105         init(n);
    106         u = stack[depth / 2 - 1];//chai bian
    107         v = stack[depth / 2];
    108         for(int i = 0;i < n - 1;i ++){
    109             if((edge_u_v[i][0] == u && edge_u_v[i][1] == v)
    110             || (edge_u_v[i][1] == u && edge_u_v[i][0] == v)) ;
    111             else{
    112                 addedge(edge_u_v[i][0],edge_u_v[i][1]);
    113                 addedge(edge_u_v[i][1],edge_u_v[i][0]);
    114             }
    115         }
    116 
    117         int seperation = stack[depth / 2];//the seperation of left and right
    118         int seperation1 = stack[(depth - 1) / 2];
    119         int long_depth = depth;
    120         depth = 1;
    121         bfs(seperation);
    122         for(int i = 0;i <= n;i ++) t_vis[i] = vis[i];
    123         for(int i = 0;i <= n;i ++) vis[i] = 0;
    124         bfs(ind);
    125         ans_one = stack[depth/2];//if depth&1 mid else right
    126         depth_one = depth;
    127 
    128         if(long_depth&1){
    129             addedge(u,v);
    130             addedge(v,u);
    131             t_vis[seperation] = 0;
    132         }else{
    133             seperation = seperation1;
    134         }
    135         depth = 1;
    136         for(int i = 0;i <= n;i ++) vis[i] = t_vis[i];
    137         bfs(seperation);
    138         for(int i = 0;i <= n;i ++) vis[i] = t_vis[i];
    139         bfs(ind);
    140         if(depth & 1) ans_two = stack[depth/2];
    141         else ans_two = stack[(depth-1)/2];
    142         depth_two = depth;
    143 
    144         if(ans_one == ans_two){
    145             printf("%d %d %d
    ",long_depth/2,ans_one,(ans_one == 1)?2:1);
    146         }else{
    147             printf("%d %d %d
    ",max(depth_one/2,depth_two/2),ans_one,ans_two);
    148         }
    149 
    150     }
    151     return 0;
    152 }
    View Code
  • 相关阅读:
    IIS 404.17 错误解决方案
    复制文件夹
    Sliverlight Slide 的左右滑动
    Web前端学习第三天——————HTML篇.013图片格式
    Web前端学习第三天——————HTML篇.010布局与选择器
    Web前端学习第二天——————HTML篇.009css
    Web前端学习第一天—————HTML篇.004个人简历制作
    Web前端学习第二天——————HTML篇.008表单
    Web前端学习第一天——————HTML篇.004百度云盘目录
    Web前端学习第三天——————HTML篇.011选择器权重
  • 原文地址:https://www.cnblogs.com/-sunshine/p/4029172.html
Copyright © 2011-2022 走看看