• 2018中国大学生程序设计竞赛


    Tree and Permutation

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 0    Accepted Submission(s): 0


    Problem Description
    There are N vertices connected by N1 edges, each edge has its own length.
    The set { 1,2,3,,N } contains a total of N! unique permutations, let’s say the i-th permutation is Pi and Pi,j is its j-th number.
    For the i-th permutation, it can be a traverse sequence of the tree with N vertices, which means we can go from the Pi,1-th vertex to the Pi,2-th vertex by the shortest path, then go to the Pi,3-th vertex ( also by the shortest path ) , and so on. Finally we’ll reach the Pi,N-th vertex, let’s define the total distance of this route as D(Pi) , so please calculate the sum of D(Pi) for all N! permutations.
     
    Input
    There are 10 test cases at most.
    The first line of each test case contains one integer N ( 1N105 ) .
    For the next N1 lines, each line contains three integer XY and L, which means there is an edge between X-th vertex and Y-th of length L ( 1X,YN,1L109 ) .
     
    Output
    For each test case, print the answer module 109+7 in one line.
     
    Sample Input
    3 1 2 1 2 3 1 3 1 2 1 1 3 2
     
    Sample Output
    16 24

    题意:求最小的n个点的全排列路径之和

    分析:将所有n个点的排列写出来,容易发现每两个点的最小路径对答案贡献了2*(n-1)!*dis[i][j]

      所以求一遍每两个点的最短路径,即2*(n-1)!*dis[i][j]

      求任意两点的最短路径参考博客:https://blog.csdn.net/acmore_xiong/article/details/51958921

    AC代码:

    #pragma comment(linker, "/STACK:102400000,102400000")
    #include<iostream>
    #include<vector>
    #include<memory.h>
    using namespace std;
    #define ll long long
    typedef pair<int,int> PII;
    const ll mod = 1e9+7;
    const int N = 1e5+10;
    
    struct nd
    {
        int v,len;
    };
    vector<nd>vet[N];
    long long n,dp[N],sum[N],c[N];
    
    void DFS(int rt,int fa)
    {
        sum[rt]=1;
        for(int i=0; i<vet[rt].size(); i++)
        {
            int son=vet[rt][i].v;
            int len=vet[rt][i].len;
            if(son==fa) continue;
            DFS(son,rt);
            (sum[rt]+=sum[son])%=mod;
            dp[rt]+=(dp[son]+(sum[son]*(n-sum[son]))%mod*len%mod)%mod;
            dp[rt] = (dp[rt]+mod)%mod;
        }
    }
    
    void init() {
        memset(sum,0,sizeof(sum));
        memset(dp,0,sizeof(dp));
    }
    
    void solve() {
        ll u,v,len;
        while(cin>>n)
        {
            for(int i=0; i<=n; i++)vet[i].clear();
            for(int i=1; i<=n-1; i++)
            {
                cin>>u>>v>>len;
                u--,v--;
                nd p1,p2;
                p1.v=v,p2.v=u;
                p1.len=p2.len=len;
                vet[u].push_back(p1);
                vet[v].push_back(p2);
            }
            init();
            DFS(0,-1);
            cout<<dp[0]*c[n]%mod<<endl;
        }
    }
    
    
    
    int main()
    {
        ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
        c[2]=2;
        for(int i=3;i<N;i++) c[i]=(i-1)*c[i-1]%mod;
        solve();
        return 0;
    }
    

      

  • 相关阅读:
    根据会员权限显示指定字段教程与源码
    关键字替换排除HTML标签属性字符
    C# 图片处理(压缩、剪裁,转换,优化)
    点击按钮后表单自动提交的问题
    浏览器中添加收藏当前网页
    Javascript基础知识整理
    JS中不同类型的值比较问题
    ACM训练场
    sencha/extjs 动态创建grid表格
    sencha 报错问题汇总
  • 原文地址:https://www.cnblogs.com/l609929321/p/9535072.html
Copyright © 2020-2023  润新知