51nod 1405 树的距离之和(思维)

给定一棵树,求到每一个点到其他所有点的最短距离之和
假定一个根
然后求出该点的答案值
根据我们dfs的顺序,这颗树也是可以唯一确定的
任意一个子节点的值 = 总节点数+父节点值-2*子节点的子树节点数(包括自己)
不知道怎么想出来的,反正就是可以

#include <iostream>
#include <vector>
#include <set>
#include <map>
using namespace std;
#define debug(x) std::cerr << #x << " = " << (x) << std::endl
typedef long long LL;
const int MAXN = 1e5 + 17;
const int MOD = 1e9 + 7;
vector<LL > G[MAXN],vis,son,vis1;
LL ans[MAXN],n;
void ini(int p,int x)
{
    ans[0]+=x,vis[p] = 1;
    for(auto i : G[p])
        if(!vis[i])
        {
            ini(i,x+1);
            son[p] += son[i]; 
        }
}
void dfs(int p)
{
    vis1[p] = 1;
    for(auto i : G[p])
    {
        // debug(vis[i]);
        if(!vis1[i])
        {
            ans[i] = ans[p]+n-2*son[i];
            // debug(i);
            // debug(son[i]);
            dfs(i);
        }
    }
}   
int main(int argc, char const *argv[])
{
#ifdef noob
    freopen("Input.txt", "r", stdin);
    freopen("Output.txt", "w", stdout);
#endif
    cin>>n;
    for (int i = 0; i < n-1; ++i)
    {
        int u,v;
        cin>>u>>v;
        u--,v--;
        G[u].push_back(v);
        G[v].push_back(u);
    }
    vis.resize(n,0);
    son.resize(n,1);
    ini(0,0);
    vis1.resize(n,0);
    dfs(0);
    //debug(ans[0]);
    for (int i = 0; i < n; ++i)
    {
        //debug(son[i]);
        // debug(ans[i]);
        cout<<ans[i]<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_37802215/article/details/81073498
今日推荐