题目意思:给一棵树,找到俩个不相交的通路,使得这俩个通路的长度和乘机最大;

解法:

  小哥一看呵呵 这不就是枚举点 然后求俩边的树的直径在相乘求个最大值的题么!

  呵呵 这个N 有100000 当时就不玩了;

  学长指导了下我;

  俺会了!/灯泡

  在枚举点在书的直径上时点的左右的最长的链无非这几种情况如图(红色是树得直径)(蓝色和绿色是俩种情况)

  无非就 蓝色和绿色这个俩种,所以这个答案和直径有很大的关系!

不在直径上时:一边肯定是直径了另一半呢?如图;

  解的过程:

    1: 想求出直径的点顺序的 存在一个数组内;

    2: 求出和每个直径上节点相邻的  最大和次大 和直径不相连的  链的 长度  并求出Max(这个链的点都不在直径上)

    3:O(n)枚举点并求出这个点的左右的长度最值

    4:由3的结果求出最大的ANS ,在和树得直径*Max取最值

  over:

代码

#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;
const int INF=0x7fffffff;
const int maxn=;
struct Edge
{
int to,pre;
Edge (int to=,int pre=):to(to),pre(pre){}
};
Edge edge[maxn*];
int head[maxn],pos;
bool vis[maxn];
bool in_line[maxn];
int ko[maxn],pos_ko;
int dp[maxn][];
int dp1[maxn],dp2[maxn];
struct info
{
int p,pre;
};
info que[maxn];
void inint()
{
memset(head,-,sizeof(head));
pos=pos_ko=;
memset(dp,,sizeof(dp));
memset(in_line,false,sizeof(in_line));
memset(dp1,,sizeof(dp1));
memset(dp2,,sizeof(dp2));
}
void add_edge(int s,int to)
{
edge[pos]=Edge(to,head[s]);
head[s]=pos++;
}
void make(int P)
{
if(que[P].pre!=-)make(que[P].pre);
ko[pos_ko++]=que[P].p;
in_line[que[P].p]=true;
}
int bfs(int t,bool flag)
{
memset(vis,false,sizeof(vis));
int h=,r=;
que[].p=t;
que[].pre=-;
vis[t]=true;
int x;
while(h<r)
{
x=que[h++].p;
for(int i=head[x];~i;i=edge[i].pre)
{
Edge &tmp=edge[i];
if(!vis[tmp.to])
que[r].p=tmp.to,
que[r++].pre=h-,
vis[tmp.to]=true;
}
}
if(flag)make(r-);
return que[r-].p;
}
void get_it(int key,int t)
{
if(key>dp[t][])dp[t][]=dp[t][],
dp[t][]=key;
else if(key>dp[t][])
dp[t][]=key;
}
int Max;
int dfs(int pa,int &s,int &t)
{
int key,ans=;
for(int w=head[s];~w;w=edge[w].pre)
{
Edge &tmp=edge[w];
if(tmp.to==pa||in_line[tmp.to])continue;
key=dfs(s,tmp.to,t);
if(pa==-) get_it(key,t);
if(pa!=-)
{
if(ans)
Max=max(Max,ans-+key);
else
Max=max(Max,key);
}
ans=max(ans,key+);
}
if(pa==-)Max=max(Max,ans-);
return ans==?:ans;
}
void solve(int &n)
{ long long ans=;
Max=;
int p1=bfs(,false),p2=bfs(p1,true);
int Max1;
for(int i=;i<pos_ko;i++)
dfs(-,ko[i],i);
ans=(pos_ko-)*Max;
--pos_ko;
for(int i=;i<pos_ko;i++)
{
dp1[i]=max(dp1[i-],i+dp[i][]);
dp1[i]=max(dp1[i],dp[i][]+dp[i][]);
}
for(int i=pos_ko-;i>=;i--)
{
dp2[i]=max(dp2[i+],pos_ko-i+dp[i][]);
dp2[i]=max(dp2[i],dp[i][]+dp[i][]);
}
for(int i=;i<pos_ko;i++)
ans=max(ans,(long long)dp1[i]*dp2[i+]);
ans=max(ans,(long long ));
printf("%lld\n",ans);
}
int main()
{
int n;
int a,b;
while(~scanf("%d",&n))
{
inint();
for(int i=;i<=n;i++)
{
scanf("%d%d",&a,&b);
add_edge(a,b);
add_edge(b,a);
}
solve(n);
}
return ;
}

SPOJ TWOPATHS Two Paths的更多相关文章

  1. SPOJ Two Paths

    Description 给定一个无向图,含有一定的路.从中找出两个最长的路径(每条路径有一些相通路组成)这两个路径不能经过公共的点,求何时二路径的乘积最大. 本题给出的无向图是一棵树,每边权值为1. ...

  2. BZOJ 2588: Spoj 10628. Count on a tree [树上主席树]

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MBSubmit: 5217  Solved: 1233 ...

  3. [LeetCode] Binary Tree Paths 二叉树路径

    Given a binary tree, return all root-to-leaf paths. For example, given the following binary tree: 1 ...

  4. [LeetCode] Unique Paths II 不同的路径之二

    Follow up for "Unique Paths": Now consider if some obstacles are added to the grids. How m ...

  5. [LeetCode] Unique Paths 不同的路径

    A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). The ...

  6. SPOJ DQUERY D-query(主席树)

    题目 Source http://www.spoj.com/problems/DQUERY/en/ Description Given a sequence of n numbers a1, a2, ...

  7. leetcode : Binary Tree Paths

    Given a binary tree, return all root-to-leaf paths. For example, given the following binary tree: 1 ...

  8. SPOJ GSS3 Can you answer these queries III[线段树]

    SPOJ - GSS3 Can you answer these queries III Description You are given a sequence A of N (N <= 50 ...

  9. UVA 10564 Paths through the Hourglass[DP 打印]

    UVA - 10564 Paths through the Hourglass 题意: 要求从第一层走到最下面一层,只能往左下或右下走 问有多少条路径之和刚好等于S? 如果有的话,输出字典序最小的路径 ...

随机推荐

  1. 8张图理解Java(转)

    一图胜千言,下面图解均来自Program Creek 网站的Java教程,目前它们拥有最多的票选.如果图解没有阐明问题,那么你可以借助它的标题来一窥究竟. 1.字符串不变性 下面这张图展示了这段代码做 ...

  2. MySQLdb的安装与使用

    一.安装 安装已编译版本号(此方法简便快捷): http://www.codegood.com/downloads 依据自己系统下载,双击安装,搞定 然后import MySQLdb.查看是否成功 我 ...

  3. 数据结构《17》---- 自己主动补齐之《二》----Ternary Search Tree

    一. 序言 上一篇文章中,给出了 trie 树的一个实现. 能够看到,trie 树有一个巨大的弊病,内存占用过大. 本文给出还有一种数据结构来解决上述问题---- Ternary Search Tre ...

  4. win7如何清理图标缓存

    rem 关闭Windows外壳程序explorer taskkill /f /im explorer.exe rem 清理系统图标缓存数据库 attrib -h -s -r "%userpr ...

  5. Android 增量更新实例(Smart App Updates)

    原地址:http://my.oschina.net/liucundong/blog/160436 官方说明 实现原理 实现 (1)生成差异包 (2)使用旧apk+差异包,在客户端合成新apk 注意事项 ...

  6. Linux 利用hosts.deny 防止暴力破解ssh(转)

    一.ssh暴力破解 利用专业的破解程序,配合密码字典.登陆用户名,尝试登陆服务器,来进行破解密码,此方法,虽慢,但却很有效果. 二.暴力破解演示 2.1.基础环境:2台linux主机(centos 7 ...

  7. 【UVA】10012 - How Big Is It?(暴力)

    使用DFS枚举所有的安排.每次加入后,当一个圆.他的立场是最大的,并已加入了圆环中的所有切线位置前面. 14383635 10012 option=com_onlinejudge&Itemid ...

  8. VSTO 得到Office文档的选中内容(Word、Excel、PPT、Outlook)

    原文:VSTO 得到Office文档的选中内容(Word.Excel.PPT.Outlook) 目的:得到在Word.Excel.PPT.Outlook中选中的一段内容. Word: private ...

  9. TkinterGUI - 初识Tkinter

    前言 近期有写一个简单GUI程序的点子,具体写什么就不说了,但一个要求就是有跨平台的功能. 确切的讲,是我希望这个程序写好后能同时在Windows和Linux下运行,而且要方便随时修改. 对于编程语言 ...

  10. [LeetCode] Search for a Range [34]

    题目 Given a sorted array of integers, find the starting and ending position of a given target value. ...