题目含义
就是建一个树,让你求最大直径
下面用分别用DP和DFS的方法
题目代码
#include<iostream> #include<stdio.h> #include<string.h> using namespace std; const int maxn=5e4+7; int n,m,tot,a,b,c,ans; char cc; int head[maxn],d[maxn]; struct node{ int to,w,next; }edge[maxn*2]; void add(int u,int v,int w){ edge[tot].to=v; edge[tot].w=w; edge[tot].next=head[u]; head[u]=tot++; } void dfs(int u,int fa){ for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].to; if(v==fa)continue; dfs(v,u); ans=max(ans,d[u]+d[v]+edge[i].w); d[u]=max(d[u],d[v]+edge[i].w); } } int main(){ scanf("%d%d",&n,&m); tot=0; memset(d,0,sizeof(d)); memset(head,-1,sizeof(head)); for(int i=1;i<=m;i++){ scanf("%d%d%d %c",&a,&b,&c,&cc); add(a,b,c);add(b,a,c); } ans=0; dfs(1,0); printf("%d\n",ans); return 0; }
树形DP
树形DP的思想是用任意一个节点作为根
然后找出这个根的深度最大的两个子树
这两个子树的深度之和就是最大直径
#include<iostream> #include<stdio.h> #include<string.h> using namespace std; const int maxn=5e4+7; int n,m,tot,a,b,c,ans; char cc; int head[maxn],dis[maxn]; struct node{ int to,w,next; }edge[maxn*2]; void add(int u,int v,int w){ edge[tot].to=v; edge[tot].w=w; edge[tot].next=head[u]; head[u]=tot++; } void dfs(int u,int fa){ for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].to; if(v==fa)continue; dis[v]=dis[u]+edge[i].w; dfs(v,u); } } int main(){ scanf("%d%d",&n,&m); tot=0; memset(head,-1,sizeof(head)); for(int i=1;i<=m;i++){ scanf("%d%d%d %c",&a,&b,&c,&cc); add(a,b,c);add(b,a,c); } int ans_max=0,ans_index=0; memset(dis,0,sizeof(dis)); dfs(1,0); for(int i=1;i<=n;i++){ if(dis[i]>ans_max){ ans_max=dis[i]; ans_index=i; } } memset(dis,0,sizeof(dis)); dfs(ans_index,0); for(int i=1;i<=n;i++) if(dis[i]>ans_max) ans_max=dis[i]; printf("%d\n",ans_max); return 0; }
两次DFS
两次DFS的思想是先用任意一个节点作为根
找到离他最远的节点的深度ANS_MAX和这个节点的位置ANS_INDEX
然后再以找到的这个节点作为根
找出离他最远的节点的深度,与ANS_MAX做比较,就能找出最大直径
原文地址:https://www.cnblogs.com/helman/p/11271948.html
时间: 2024-10-24 14:59:07