給你一棵樹,找出兩個葉子之間的最短距離。
第一種是個純dfs+稍微的剪枝,從每一個葉子出發,dfs直到找到一個新的葉子,更新最短距離。781ms
#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
#include<queue>
#define MAXN 10001
#define INF 2147483647
using namespace std;
int n;
vector<int>g[MAXN],w[MAXN];
int angel[MAXN];
int maxx;
bool vis[MAXN];
void dfs(int ori,int cur,int dis)
{
if(dis>=maxx) return ;
vis[cur]=true;
if(angel[cur]==1&&cur!=ori)
{
maxx=min(maxx,dis);
return ;
}
for(int i=0; i<(int)g[cur].size(); i++)
{
int t=g[cur][i];
if(!vis[t]&&w[cur][i]+dis<maxx)
dfs(ori,t,w[cur][i]+dis);
}
}
int main()
{
// freopen("in.txt","r",stdin);
while(scanf("%d",&n)!=EOF&&n)
{
for(int i=0; i<=n; i++)
g[i].clear(),w[i].clear(),angel[i]=0;
maxx=INF;
for(int i=0; i<n-1; i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
angel[a]++,angel[b]++;
g[a].push_back(b),w[a].push_back(c);
g[b].push_back(a),w[b].push_back(c);
}
for(int i=1; i<=n; i++)
if(angel[i]==1)
{
memset(vis,false,sizeof(vis));
dfs(i,i,0);
}
printf("%d\n",maxx);
}
return 0;
}
第二種是新接觸的樹形dp,從任意一個節點出發,dfs回溯,dp[cur][0]表示cur節點到葉子的最短距離,dp[cur][1]表示cur節點到葉子的次短距離。注意dp數組的初始化,(每一個葉子到葉子的最短距離是0)。PS.樹形dp,它的原理和名字很像。dp[cur][0]=min{dp[cur][0],dp[u][0]+dis(u,cur)],因爲父節點cur的dp值通過子節點來得出,所以通過回溯遞歸求解每一個節點的dp[][].
#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
#define MAXN 10010
#define INF 20000000
using namespace std;
vector<int>g[MAXN],w[MAXN];
int n,dp[MAXN][2],degree[MAXN];
bool vis[MAXN];
int maxx;
void dfs(int cur)
{
vis[cur]=true;
for(int i=0; i<(int)g[cur].size(); i++)
{
int t=g[cur][i];
if(!vis[t])
{
dfs(t);
if(w[cur][i]+dp[t][0]<dp[cur][0])
{
dp[cur][1]=dp[cur][0];
dp[cur][0]=w[cur][i]+dp[t][0];
}
else if(w[cur][i]+dp[t][0]<dp[cur][1])
dp[cur][1]=w[cur][i]+dp[t][0];
// printf("cur:%d %d %d\n",cur,dp[cur][0],dp[cur][1]);
}
}
maxx=min(maxx,dp[cur][0]+dp[cur][1]);
}
int main()
{
freopen("in.txt","r",stdin);
while(scanf("%d",&n)!=EOF&&n)
{
for(int i=0; i<=n; i++)
g[i].clear(),w[i].clear(),degree[i]=0;
for(int i=1; i<n; i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
degree[a]++,degree[b]++;
g[a].push_back(b),g[b].push_back(a);
w[a].push_back(c),w[b].push_back(c);
}
for(int i=1; i<=n; i++)
{
dp[i][0]=dp[i][1]=INF;
if(degree[i]==1)
dp[i][0]=0;
}
memset(vis,false,sizeof(vis));
maxx=INF;
dfs(1);
printf("%d\n",maxx);
}
return 0;
}