51Nod-1405-树的距离之和
来源:互联网 发布:淘宝收入来源 编辑:程序博客网 时间:2024/06/03 15:56
ACM模版
描述
题解
根据题意,这是一颗树,所以每两点之间的路径一定是唯一的。这里让求所有点到第i个结点的距离和,其实也就是其他所有结点到第i个结点的距离和。
通过观察发现,只要我们找到了一个点对应的结果,那么其他所有的点都可以通过这个结果扩展出来,利用边的关系。比如说,我们知道了第一个结点对应的结果,并且知道第一个和第二个存在连边,那么一定可以通过第一个的结果求得第二个结果……以此类推。
所以,我们先dfs,求第一个结点的对应结果(当做根,也可以是别的结点当做根),并且存储该树每个枝杈上的后代数目(包括其本身),这个数据对求其他结果至关重要,接着我们再通过第二个dfs扩展出其他结果即可。
另外附一份树归的解法(Two)……
代码
One:
#include <iostream>#include <vector>#include <cstdio>using namespace std;typedef long long ll;const int MAXN = 1e5 + 5;int n;ll res[MAXN];int des[MAXN];vector<int> node[MAXN];void dfs(int lastPos, int pos, int power){ for (int i = 0; i < node[pos].size(); i++) { if (node[pos][i] != lastPos) { res[1] += (node[node[pos][i]].size() - 1) * power; dfs(pos, node[pos][i], power + 1); des[pos] += des[node[pos][i]]; } } return ;}void dfs_(int lastPos, int pos){ for (int i = 0; i < node[pos].size(); i++) { if (node[pos][i] != lastPos) { res[node[pos][i]] = res[pos] - des[node[pos][i]] + n - des[node[pos][i]]; dfs_(pos, node[pos][i]); } } return ;}int main(int argc, const char * argv[]){// freopen("/Users/zyj/Desktop/input.txt", "r", stdin); cin >> n; int x, y; for (int i = 1; i < n; i++) { scanf("%d %d", &x, &y); node[x].push_back(y); node[y].push_back(x); } res[1] = node[1].size(); for (int i = 1; i <= n; i++) { des[i] = 1; } dfs(0, 1, 2); dfs_(0, 1); for (int i = 1; i <= n; i++) { printf("%lld\n", res[i]); } return 0;}
Two:
#include <iostream>#include <cstdio>#include <cstring>#define MAXN 100009using namespace std;typedef struct{ int a; int next;} point;point p[2 * MAXN];typedef struct{ long long n; long long w;} r;r R;int dis[MAXN];long long dp[2 * MAXN][2];void DFS(int a, int last){ int i; long long ans = 0, count = 0; for (i = dis[a]; i != 0; i = p[i].next) { if (p[i].a != last) { if (dp[i][0] != -1) { ans += dp[i][0] + dp[i][1]; count += dp[i][1]; } else { DFS(p[i].a, a); dp[i][0] = R.w; dp[i][1] = R.n; ans += R.w + R.n; count += R.n; } } } R.n = count + 1; R.w = ans; return ;}int main (){ int N, k = 1, a, b; memset(dp, -1, sizeof(dp)); scanf("%d", &N); for (int i = 1; i < N; i++) { scanf("%d%d", &a, &b); p[k].a = a; p[k].next = dis[b]; dis[b] = k++; p[k].a = b; p[k].next = dis[a]; dis[a] = k++; } for (int i = 1, sz = N + 1; i < sz; i++) { DFS(i, 0); printf("%lld\n", R.w); } return 0;}
0 0
- 51Nod-1405-树的距离之和
- 51nod 1405 树的距离之和
- 51nod 1405 树的距离之和
- 51nod-1405 树的距离之和
- 51nod 1405 树的距离之和
- 51nod 1405 树的距离之和
- 51nod 1405 树的距离之和
- 51nod 1405 树的距离之和
- 51Nod 1405 树的距离之和(dp)
- 51Nod 1405 树的距离之和(树形dp)
- 51NOD-1405 树的距离之和(树形DP)
- 51nod 1405 树的距离之和(树型dp)
- 51nod 1405 树的距离之和【树型dp】
- 51nod 1405 树的距离之和(DP)
- 51nod 1405 树的距离之和【树形dp】
- 51nod 1405 树的距离之和 (树形dp)
- 51nod 1405 树的距离之和(DFS)
- 51nod 1405 树的距离之和 搜索+DP
- Codeforces Round #371 (Div. 2) A. Meeting of Old Friends 数学、A题第三次被系统hack了 (┬_┬)、集合交集
- Node.js JSON模块
- light oj 1017 简单区间dp...新学会的东西
- findIndex Java 实现
- Check if tree b is part of tree a JAVA 实现
- 51Nod-1405-树的距离之和
- C#入门学习篇之第一天
- picasso无法更新控件上显示的拍照后的图片
- Lucene学习笔记1--lucene开篇hello lucene
- oracle实例诡异down的真实原因
- HDU 5446 lucas定理 + 中国剩余定理
- 【c++】指针参数是如何传递内存的
- form表单与fiddler抓包
- Day17对话框