题意:求树上最长路径和这样的路径数目
思路:题目的难点在于统计数目,所以我们需要换一种dp思路,dp[i]表示以i为根的子树上的最长路(这样的最长路必定是通过i节点的),我们再去求所有节点的最大值就是要求的最大值了。
在研究如何统计数量,我们可以设node[u]表示在以u为根的子树上最长路的数量,那么node[u]=node[v](或者node[u]=node[u]+node[v])。
代码:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#include <map>
#include <vector>
#include <set>
#include <string>
#include <math.h>
#include <stack>
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
#define inf 0x3f3f3f3f
int n,m;
int num;
int head[maxn];
int dp[maxn];
int ans,k;
int node[maxn];
struct Edge
{
int u,v,next,w;
}edge[maxn<<1];
void addEdge(int u,int v,int w)
{
edge[num].u=u;
edge[num].v=v;
edge[num].w=w;
edge[num].next=head[u];
head[u]=num++;
}
void init()
{
num=0;
memset(head,-1,sizeof(head));
memset(dp,0,sizeof(dp));
}
void dfs(int u,int fa)
{
int i,v,tmp;
dp[u]=0;
node[u]=1;
for(i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v,w=edge[i].w;
if(v==fa) continue;
dfs(v,u);
tmp=dp[v]+w;
if(tmp+dp[u]>ans)
{
ans=tmp+dp[u];
k=node[u]*node[v];
}
else if(tmp+dp[u]==ans)
{
k+=node[u]*node[v];
}
if(tmp>dp[u])
{
dp[u]=tmp;
node[u]=node[v];
}
else if(tmp==dp[u])
{
node[u]+=node[v];
}
}
}
int main(int argc, char const *argv[])
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
while(scanf("%d",&n)!=EOF)
{
init();
for(int i=1;i<n;i++)
{
int x,y,w;
scanf("%d%d%d",&x,&y,&w);
addEdge(x,y,w);
addEdge(y,x,w);
}
ans=-inf,k=0;
dfs(1,1);
// for(int i=1;i<=n;i++)
// {
// printf("%d %d\n",dp[i],node[i]);
// }
printf("%d %d\n",ans,k);
}
return 0;
}