标签:
Description
Input
Output
Sample Input
5 1 1 2 1 3 1 1 1
Sample Output
3 2 3 4 4
给出电脑之间连接的关系,和相互之间的长度,求每台电脑到最远的一个的距离是多少。
对于一个点i来说,i能到的最远距离可能有两种情况:
1.由i走向i的子节点存在最远长度。(向下)
2.由i走向i的父节点存在最远长度。 (向上)
dp[i][0]记录节点i向下的最长距离,belong[i][0]记录向下最长路径经过的i的子节点。
dp[i][0]记录节点i向下的第二长距离,belong[i][0]记录向下第二长路径经过的i的子节点。
flag[i] = 0代表i的父节点的最长路径不经过i, = 1 代表i的父节点的最长路径经过i
状态转移方程:先由dfs,找出所有点向下的距离,然后由上向下层次遍历
设 i是j的父节点
如果节点j的flag[j] = 0 ,那么它的最远距离应该是dp[j][0] 和 i的最远距离+i到j的距离 中的最大值。
如果节点j的flag[j] = 1 ,那么它的最远距离应该是 dp[j][0] 和 i的非包含j的路径的距离+i到j的距离 中的最大值。
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std ; struct node{ int u , v , w ; int next ; }edge[11000]; int head[11000] , cnt ; int dp[11000][2] , flag[11000] , belong[11000][2]; queue <int> que ; void add(int u,int v,int w) { edge[cnt].u = u ; edge[cnt].v = v ; edge[cnt].w = w ; edge[cnt].next = head[u] ; head[u] = cnt++ ; } void dfs(int u) { if( head[u] == -1 ) return ; int i , v , k1 , k2 ; for( i = head[u] ; i != -1 ; i = edge[i].next ) { v = edge[i].v ; dfs(v) ; if( dp[v][0]+edge[i].w > dp[u][0] ) { dp[u][1] = dp[u][0] ; belong[u][1] = belong[u][0] ; dp[u][0] = dp[v][0]+edge[i].w ; belong[u][0] = v ; } else if( dp[v][0]+edge[i].w > dp[u][1] ) { dp[u][1] = dp[v][0]+edge[i].w ; belong[u][1] = v ; } } } int main() { int n , u , v , w ; int i ; while( scanf("%d", &n) != EOF ) { memset(flag,0,sizeof(flag)) ; memset(dp,0,sizeof(dp)) ; memset(head,-1,sizeof(head)) ; memset(belong,0,sizeof(belong)) ; cnt = 0 ; add(0,1,0) ; for(i = 2 ; i <= n ; i++) { scanf("%d %d", &u, &w) ; add(u,i,w) ; } dfs(1) ; while( !que.empty() ) que.pop() ; que.push(0) ; while( !que.empty() ) { u = que.front() ; que.pop() ; for(i = head[u] ; i != -1 ; i = edge[i].next) { v = edge[i].v ; if( flag[v] ) { if( dp[v][0] + edge[i].w == dp[u][0] ) { if( dp[u][1]+edge[i].w > dp[v][0] ) { flag[ belong[v][0] ] = 1; dp[v][1] = dp[v][0] ; dp[v][0] = dp[u][1]+edge[i].w ; } else if( dp[u][1] + edge[i].w > dp[v][1] ) { flag[ belong[v][0] ] = 1 ; dp[v][1] = dp[u][1] + edge[i].w ; } else { flag[ belong[v][0] ] = 1 ; flag[ belong[v][1] ] = 1 ; } } else { if( dp[u][0]+edge[i].w > dp[v][0] ) { flag[ belong[v][0] ] = 1; dp[v][1] = dp[v][0] ; dp[v][0] = dp[u][0]+edge[i].w ; } else if( dp[u][0] + edge[i].w > dp[v][1] ) { flag[ belong[v][0] ] = 1 ; dp[v][1] = dp[u][0] + edge[i].w ; } else { flag[ belong[v][0] ] = 1 ; flag[ belong[v][1] ] = 1 ; } } } else { if( dp[u][0]+edge[i].w > dp[v][0] ) { flag[ belong[v][0] ] = 1; dp[v][1] = dp[v][0] ; dp[v][0] = dp[u][0]+edge[i].w ; } else if( dp[u][0] + edge[i].w > dp[v][1] ) { flag[ belong[v][0] ] = 1 ; dp[v][1] = dp[u][0] + edge[i].w ; } else { flag[ belong[v][0] ] = 1 ; flag[ belong[v][1] ] = 1 ; } } que.push(v) ; } } for(i = 1 ; i <= n ; i++) printf("%d\n", dp[i][0]) ; } return 0; }
标签:
原文地址:http://blog.csdn.net/winddreams/article/details/42833559