频繁调用的函数 :如果某个函数被频繁调用,使用inline
可以减少调用开销,提高程序性能。例如,在循环中频繁调用的函数
求树的直径:
两次dfs
还有求最长链和次长链的写法(max(dp[x][0],dp[x][1])):
cpp
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int n,head[N],nxt[N<<1],to[N<<1],cnt;
//head
inline void add(int x,int y)
{
++cnt;
nxt[cnt]=head[x];
head[x]=cnt;
to[cnt]=y;
return;
}
int dp[N][2];
void dfs(int x,int fa)
{
for(int i=head[x];i;i=nxt[i])
{
int y=to[i];
if(y==fa) continue;
dfs(y,x);
if((dp[y][0]+1)>dp[x][0])
//这里都是dp[y][0]进行比较
//+1体现了数据的变化
dp[x][1]=dp[x][0],dp[x][0]=dp[y][0]+1;
else if((dp[y][0]+1)>dp[x][1])
dp[x][1]=dp[y][0]+1;
}//如果大于x的最长链则
//dp[x][1]更新为新的最大链值
//原来的最大值变为新的次大值
//不大于最长链但是大于次长链就更新次长链
return;
//那就是dp[x]+dp[y]算出的是直径包含的边,点比边多1然后+1,最后输出次大长的链再-1
}
int main()
{
cin>>n;
for(int i=2;i<=n;i++)
{
int x,y;cin>>x>>y;
add(x,y),add(y,x);
}
dfs(1,0);
int ans=0;
for(int i=1;i<=n;i++) ans=max(ans,dp[i][0]+dp[i][1]+1);
cout<<ans-1;
return 0;
}
cpp
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int n,head[N],nxt[N<<1],to[N<<1],cnt;
//双向边开二倍
inline void add(int x,int y)
{
++cnt;//边的编号
nxt[cnt]=head[x];//将节点x当前的指向的边先给编号为cnt的边
head[x]=cnt;//节点x现在指向cnt
to[cnt]=y;//编号为cnt的边指向的节点
return;
}
int dp[N][2];
void dfs(int x, int fa) {
// 遍历当前节点x的所有邻接节点
for (int i = head[x]; i; i = nxt[i]) {
int y = to[i]; // 获取当前边的终点节点y
if (y == fa) continue; // 如果y是父节点,跳过,避免返回父节点形成环
dfs(y, x); // 递归调用dfs,以y为新的当前节点,x为新的父节点
// 更新dp值,dp[x][0]表示从节点x出发的最长路径长度,dp[x][1]表示次长路径长度
// dp[y][0] + 1表示从x到y的路径长度(加1是因为从x到y有一条边)
if ((dp[y][0] + 1) > dp[x][0]) {
// 如果从y出发的最长路径长度加1大于从x出发的当前最长路径长度
dp[x][1] = dp[x][0]; // 更新次长路径长度为原来的最长路径长度
dp[x][0] = dp[y][0] + 1; // 更新最长路径长度为从y出发的最长路径长度加1
} else if ((dp[y][0] + 1) > dp[x][1]) {
// 如果从y出发的最长路径长度加1大于从x出发的当前次长路径长度
dp[x][1] = dp[y][0] + 1; // 更新次长路径长度为从y出发的最长路径长度加1
}
}
return; // 递归返回
}
int main()
{
scanf("%d",&n);
for(int i=2;i<=n;i++)
{
int x,y;scanf("%d%d",&x,&y);
add(x,y),add(y,x);
}
dfs(1,0);
int ans=0;
for(int i=1;i<=n;i++) ans=max(ans,dp[i][0]+dp[i][1]+1);
printf("%d\n",ans-1);
return 0;
}