SPOJ TWOPATHS Two Paths
题目意思:给一棵树,找到俩个不相交的通路,使得这俩个通路的长度和乘机最大;
解法:
小哥一看呵呵 这不就是枚举点 然后求俩边的树的直径在相乘求个最大值的题么!
呵呵 这个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的更多相关文章
- SPOJ Two Paths
Description 给定一个无向图,含有一定的路.从中找出两个最长的路径(每条路径有一些相通路组成)这两个路径不能经过公共的点,求何时二路径的乘积最大. 本题给出的无向图是一棵树,每边权值为1. ...
- 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 ...
- [LeetCode] Binary Tree Paths 二叉树路径
Given a binary tree, return all root-to-leaf paths. For example, given the following binary tree: 1 ...
- [LeetCode] Unique Paths II 不同的路径之二
Follow up for "Unique Paths": Now consider if some obstacles are added to the grids. How m ...
- [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 ...
- SPOJ DQUERY D-query(主席树)
题目 Source http://www.spoj.com/problems/DQUERY/en/ Description Given a sequence of n numbers a1, a2, ...
- leetcode : Binary Tree Paths
Given a binary tree, return all root-to-leaf paths. For example, given the following binary tree: 1 ...
- 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 ...
- UVA 10564 Paths through the Hourglass[DP 打印]
UVA - 10564 Paths through the Hourglass 题意: 要求从第一层走到最下面一层,只能往左下或右下走 问有多少条路径之和刚好等于S? 如果有的话,输出字典序最小的路径 ...
随机推荐
- [Android学习笔记]ListView中含有Button导致无法响应onItemClick回调的解决办法
转自:http://www.cnblogs.com/eyu8874521/archive/2012/10/17/2727882.html 问题描述: 当ListView的Item中的控件只是一些展示类 ...
- C语言char s[] 和 char *s的差别
C语言char s[] 和 char *s的差别,以下这个回答解说的非常清晰. The difference here is that char *s = "Hello world" ...
- 超人学院Hadoop大数据技术资源分享
超人学院Hadoop大数据技术资源分享 http://bbs.superwu.cn/forum.php?mod=viewthread&tid=807&fromuid=645 很多其它精 ...
- [置顶] CentOS release 5.4 (Final)重置root密码(图文)
- IBM之MQ使用指南
随着计算机网络和分布式应用的不断发展.远程消息传递越来越成为应用系统中必不可少的组成部分. 商业消息中间件的出现保证了消息传输的可靠性,高效率和安全性,同一时候也降低了系统的开发周期. 眼下应用最多的 ...
- hdu 4685 Prince and Princess(匈牙利算法 连通分量)
看了别人的题解.须要用到匈牙利算法的强连通算法 #include<cstdio> #include<algorithm> #include<vector> #pra ...
- BlueJ的code pad
Java的REPL BlueJ的code pad实用吗?Java对(Read-Eval-Print Loop)不提供原生支持.这样的"交互式解释器"或"交互式编程环境&q ...
- Android学习-各种对话框
在android的编程中,对话框的用处是非常多的,然而,有时对对话框的需求也是不一样的,那么现在,就总结对话框的种类,以及事件的处理形势. 1.简单的对话框 public void showDialo ...
- SPARK如何使用AKKA实现进程、节点通信
SPARK如何使用AKKA实现进程.节点通信 <深入理解Spark:核心思想与源码分析>一书前言的内容请看链接<深入理解SPARK:核心思想与源码分析>一书正式出版上市 < ...
- Win7下不能查看xp系统共享的文件,解决方法
近期在做一个程序,xp执行良好.win7总是打不开文件,输入地址訪问\\192.168.0.254,发现须要输入usernamepassword 局域网内的XP电脑能够訪问WIN7的共享文件.而WIN ...