codeforce 14D 无向图 求树的长度 bfs是一种方法 先用dfs做

枚举每一条边  将树分为两部分 分别dfs求出树的直径

从一点开始最长路加次长路为树的直径

#include<iostream>

#include<vector>
#include<algorithm>
using namespace std;
vector<int> G[100000];
int n,s;
inline int max(int a,int b)//注意是inline 不然超时
{
       return a>b?a:b;
}
int dfs(int v,int x)
{
            int max1=0;
            int max2=0;
            int sum=0;
            int i;
            for(i=0;i<G[v].size();i++)
           {
                    if(G[v][i]!=x)
                    {
                           sum=max(sum,dfs(G[v][i],v));
                           if(s>max1)
                           {
                                   max2=max1;
                                   max1=s;
                           }
                           else
                                   max2=max(max2,s);
                    }
           }
           sum=max(sum,max1+max2);
           s=max1+1;
           return sum;
}
int main()
{
           while(cin>>n)
          {
                  int i,j;
                  for(i=1;i<=n;i++)
                  {
                                  G[i].clear();
                  }
                  for(i=1;i<n;i++)
                  {
                           int s,t;
                          cin>>s>>t;
                          G[s].push_back(t);
                          G[t].push_back(s);
                  }
                   int ans=0;
                   int x=0,y=0;
                   for(i=1;i<=n;i++)
                  {
                                 for(j=0;j<G[i].size();j++)
                                {
                                         s=0;
                                         x=dfs(G[i][j],i);
                                         y=dfs(i,G[i][j]);
                                        ans=max(ans,x*y);
                                 }
                  }
                  cout<<ans<<endl;
         }
         return 0;
}

时间: 2024-11-06 11:10:12

codeforce 14D 无向图 求树的长度 bfs是一种方法 先用dfs做的相关文章

php在数字前面补0得到固定长度数字的两种方法

比较基础,其实两个内置函数都能实现. 1  sprintf 语法: string sprintf(string format, mixed [args]...); 返回值: 字符串 函数种类: 资料处理 本函数用来将字符串格式化.参数 format 是转换的格式,以百分比符号 % 开始到转换字符为止.而在转换的格式间依序包括了 填空字符.0 的话表示空格填 0:空格是默认值,表示空格就放着. 对齐方式.默认值为向右对齐,负号表向左对齐. 字段宽度.为最小宽度. 精确度.指在小数点后的浮点数位数.

利用matlab求图像均值和方差的几种方法

一.求均值 % 求一副灰度图像的均值 close all; clear; clc; i=imread('d:/lena.jpg'); %载入真彩色图像 i=rgb2gray(i); %转换为灰度图 i=double(i); %将uint8型转换为double型,否则不能计算统计量 % avg1=mean(i,1); %列向量均值 % avg2=mean(i,2); %行向量均值 % avg3=mean(i); %列向量均值 [m,n]=size(i); s=0; for x=1:m for y=

求最大公约数和最小公倍数的几种方法

最大公约数: 常规方法 辗转相除法 递归法 三目运算符 + 递归 最小公倍数: 常规方法 利用最大公约数求解 示例代码: 1 #include<iostream> 2 using namespace std; 3 4 //最大公约数 5 //(1)常规方法 6 void gcd1(int a, int b) 7 { 8 int minNum = min(a, b); 9 for (int i = minNum; i >= 1; i--) 10 { 11 if (a % i == 0 &a

Python中求1到20平方的两种方法

#1.使用列表推导式 >>> [x**2 for x in range(1,21)] [1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400] #使用lambda >>> [(lambda x:x**2)(x) for x in range(1,21)] [1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144,

Java求100以内的质数的四种方法

质数: 又称素数,只能被1和它本身整除的数就是质数. 难点: 需要两层循环,外层循环99遍: 内层循环,控制除数为2到98(也就是2到被除数前面的一个数). 为什么从2开始?因为所有数都能被1整除. 需要定义一个变量flag来记录某个数是不是质数 内层循环结束后需要重新把flag重置为true 方法一: import org.junit.Test; public class Demo { @Test public void primeNumberTest() { boolean flag = t

poj2631 求树的直径裸题

题目链接:http://poj.org/problem?id=2631 题意:给出一棵树的两边结点以及权重,就这条路上的最长路. 思路:求实求树的直径. 这里给出树的直径的证明: 主要是利用了反证法: 假设 s-t这条路径为树的直径,或者称为树上的最长路 现有结论,从任意一点u出发搜到的最远的点一定是s.t中的一点,然后在从这个最远点开始搜,就可以搜到另一个最长路的端点,即用两遍广搜就可以找出树的最长路 证明: 1.设u为s-t路径上的一点,结论显然成立,否则设搜到的最远点为T则   dis(u

hdu4612 无向图中任意添加一条边后使桥的数量最少 / 无向图缩点+求树的直径

题意如上,含有重边(重边的话,俩个点就可以构成了边双连通). 先缩点成树,在求数的直径,最远的连起来,剩下边(桥)的自然最少.这里学习了树的直径求法:第一次选任意起点U,进行bfs,到达最远的一个点v(level最深)该点必然是树的直径的一个端点,,再从该点出发,bfs,到最深的一点,该点深度就是直径.(证明:先假设u,是直径上一点,S,T是直径的端点,设v!=t,则有(V,U)+(U,S)>(T,U)+(U,S),矛盾,故t=v:若u不是直径上一点,设u到直径上的一点为x,同理易证. 最后 缩

hdu4612 无向图中随意加入一条边后使桥的数量最少 / 无向图缩点+求树的直径

题意如上,含有重边(重边的话,俩个点就能够构成了边双连通). 先缩点成树,在求数的直径,最远的连起来,剩下边(桥)的自然最少.这里学习了树的直径求法:第一次选随意起点U,进行bfs,到达最远的一个点v(level最深)该点必定是树的直径的一个端点,,再从该点出发,bfs,到最深的一点.该点深度就是直径. (证明:先如果u.是直径上一点,S,T是直径的端点.设v!=t,则有(V,U)+(U,S)>(T,U)+(U,S),矛盾,故t=v:若u不是直径上一点.设u到直径上的一点为x.同理易证. 最后

Codeforces1294F. Three Paths on a Tree(两次BFS求树的直径)

题意: 给一棵树,找到三个顶点,使三个顶点两两之间路径的并集最大 思路: 必定会有一组最优解,使得 a,b是树直径上的端点. 证明: 假设某个答案取连接点x.x最远的树到达的点是s,根据树的直径算法,s是树的某个直径a的端点.假设x的最远和第二远的点组成的链是b,b就会和a有一段公共部分.我们取a和b相交部分距离s最远的那个点y.那么取这个链上点y的答案一定比x更优 用两次BFS可以求出直径的两个端点,在这个过程中还能顺便求出一个端点到树上每一点的距离.之后再用一次BFS求得另一个端点到树上每一