//晚上更新了
树上子链
求树上最长链(或者说树的直径、树上距离最远的两点距离,树中所有最短路径距离的最大值)的模板题
参考资料1(by ROCKYONE)
参考资料2(by forever_dreams)
1.树形DP(可以有效处理负边权)
2.两次dfs或bfs(无法处理负边权)
树的直径 = (在某个节点的子树中以它为端点的) 最长链 + 次长链
(连接起来可以得到一条更长的链,当然有时没有次长链,仅是一条最长链)
mx表示以i为根的子树中,i到叶子结点距离(不包括p[i])的最大值,即上面说的最长链
mx2表示以i为根的子树中,i到叶子结点距离(不包括p[i])的次大值,即上面说的次长链
ans=max(ans,max(mx+p[i],mx+mx2+p[i]))//p是点权
由于mx2>=0,所以可以直接写为ans=max(ans,mx+mx2+p[x])
#include<cstdio>
using namespace std;
#define max(a,b) (a>b ? a:b)
#define ll long long
const int N=100005;
const ll inf=-0x3f3f3f3f3f3f3f3f;
struct edge{
int v,h;
}e[N<<1];
int n,p[N],head[N],tot;
ll ans=inf;//注意点权有负数
inline void add(int u,int v){
e[++tot]=(edge){
v,head[u]
},head[u]=tot;
}
ll dfs(int x,int fa){
ll tmp,mx=0,mx2=0;//最长链与次长链初始化为0,如果链为负数我们不如不要
for (int i=head[x],v;i;i=e[i].h)
if ((v=e[i].v)^fa){
tmp=dfs(v,x);
if (tmp>mx) mx2=mx,mx=tmp;
else if (tmp>mx2) mx2=tmp;
}
ans=max(ans,mx+mx2+p[x]);
return mx+p[x];//最长链可以继续上传更新答案,但最长链和次长链连接起来不能上传
}
int main(){
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&p[i]);
for (int i=1,x,y;i<n;i++)
scanf("%d %d",&x,&y),add(x,y),add(y,x);
dfs(1,-1);
printf("%lld",ans);
}
A
J —计算A+B
//注意下这些情况++0,0++,02+++0,02+02+02
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#include <math.h>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <stack>
#define lowbit(i)((i)&(-i))
using namespace std;
typedef long long ll;
const int MAX=1e5+20;
const int INF=0x3f3f3f3f;
const int MOD=1000000007;
const int SQR=632;//633块,632个
void add(vector<int>&a,vector<int>&b)
{
vector<int>c;
int t=0;
for(int i=0;i<a.size()||i<b.size();i++)
{
if(i<a.size())t+=a[i];
if(i<b.size())t+=b[i];
c.push_back(t%10);
t/=10;
}
if(t)c.push_back(t);
while(c.back()==0&&c.size()>1)
c.pop_back();
for(int i=c.size()-1;i>=0;i--)
cout<<c[i];
}
int main()
{
string s;
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
cin>>s;
string a="",b="";
int t=0,num=0;
for(int j=0;j<s.size();j++)
{
if(s[j]=='+')
num++;
}
if(num!=1)
{
printf("skipped\n");
continue;
}
while(s[t]!='+')
{
a+=s[t];
t++;
}
t++;
while(t<s.size())
{
b+=s[t];
t++;
}
vector<int>vta,vtb;
for(int j=a.size()-1;j>=0;j--)
vta.push_back(a[j]-'0');
for(int j=b.size()-1;j>=0;j--)
vtb.push_back(b[j]-'0');
if(a==""||b=="")
printf("skipped\n");
else
{
add(vta,vtb);
cout<<endl;
}
}
return 0;
}