zoukankan      html  css  js  c++  java
  • 树上边分治-求任意两点路径的总和

    传送门http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1009&cid=812

    经过组合数学推导可得     题目要求2*(n-1)!*树上路径总和

    路径总和可以通过边dfs边计算

    每一条边的贡献为 siz*(n-siz)次 siz为子树大小

    /**
        Copyright(c)
        All rights reserved.
        Author : @klay
        Date : 2018-08-28-20.16.35
        Description : 树上任意两点路径总和
    */
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<vector>
    #include<cstring>
    #include<map>
    #include<set>
    #include<queue>
    #include<bitset>
    #include<utility>
    #include<functional>
    #include<iomanip>
    #include<sstream>
    #include<ctime>
    #include<cassert>
    #define A first
    #define B second
    #define mp make_pair
    #define pb push_back
    #define pw(x) (1ll << (x))
    #define sz(x) ((int)(x).size())
    #define all(x) (x).begin(),(x).end()
    #define rep(i,l,r) for(int i=(l);i<(r);i++)
    #define per(i,r,l) for(int i=(r);i>=(l);i--)
    #define FOR(i,l,r) for(int i=(l);i<=(r);i++)
    #define eps 1e-9
    #define PIE acos(-1)
    #define cl(a,b) memset(a,b,sizeof(a))
    #define fastio ios::sync_with_stdio(false);cin.tie(0);
    #define lson l , mid , ls
    #define rson mid + 1 , r , rs
    #define ls (rt<1)
    #define rs (ls|1)
    #define INF 0x3f3f3f3f
    #define lowbit(x) (x&(-x))
    #define sqr(a) a*a
    #define ll long long
    #define vi vector<int>
    #define pii pair<int, int>
    #define dd(x) cout << #x << " = " << (x) << ", "
    #define de(x) cout << #x << " = " << (x) << "
    "
    #define endl "
    "
    using namespace std;
    //**********************************
    const int maxn=1e5+7;
    const int mod=1e9+7;
    struct Edge
    {
        int to,dist,next;
    }edge[maxn];
    int tot,n,m,head[maxn],fac[maxn+7]={1};
    ll ans;
    //**********************************
    void Init()
    {
        tot=0;
        ans=0;
        cl(head,-1);
    }
    void getfac()
    {
        FOR(i,1,maxn)fac[i]=fac[i-1]*i%mod;
    }
    void add_edge(int from,int to,int dist)
    {
        edge[tot].to=to;
        edge[tot].dist=dist;
        edge[tot].next=head[from];
        head[from]=tot++;
    }
    int dfs(int u,int fa)
    {
        int size=1;
        for(int i=head[u];~i;i=edge[i].next){
            int v=edge[i].to;
            int siz=dfs(v,u);
            ll tmp=siz%mod*(n-siz)%mod*2%mod*(fac[n-1])%mod*edge[i].dist%mod;
            ans=(ans+tmp)%mod;
            size+=siz;
        }
        return size;
    }
    //**********************************
    int main()
    {
        getfac();
        while(~scanf("%d",&n)){
            Init();
            int u,v,w;
            rep(i,0,n-1)scanf("%d%d%d",&u,&v,&w),add_edge(u,v,w),add_edge(v,u,w);
            dfs(1,-1);
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    集训日记
    各种考试
    树上差分
    树的直径
    讲课
    adb常用命令
    关于appium的简单理解
    使用appium过程中常遇到的坑以及解决方案
    JMeter面试题
    fiddler面试题
  • 原文地址:https://www.cnblogs.com/klaycf/p/9550841.html
Copyright © 2011-2022 走看看