zoukankan      html  css  js  c++  java
  • 排序

    Usoperanto

    Usoperanto is an artificial spoken language designed and regulated by Usoperanto Academy. The academy is now in study to establish Strict Usoperanto, a variation of the language intended for formal documents.

    In Usoperanto, each word can modify at most one other word, and modifiers are always put before modifiees. For example, with a noun uso ("truth") modified by an adjective makka ("total"), people say makka uso, not uso makka. On the other hand, there have been no rules about the order among multiple words modifying the same word, so in case uso is modified by one more adjectivebeta ("obvious"), people could say both makka beta uso and beta makka uso.

    In Strict Usoperanto, the word order will be restricted according to modification costs. Words in a phrase must be arranged so that the total modification cost is minimized. Each pair of a modifier and a modifiee is assigned a cost equal to the number of letters between the two words; the total modification cost is the sum of the costs over all modifier-modifiee pairs in the phrase. For example, the pair of makka and uso in a phrase makka beta uso has the cost of 4 for beta (four letters). As the pair of beta and usohas no words in between and thus the cost of zero, makka beta uso has the total modification cost of 4. Similarly beta makka usohas the total modification cost of 5. Applying the "minimum total modification cost" rule, makka beta uso is preferred to beta makka uso in Strict Usoperanto.

    Your mission in this problem is to write a program that, given a set of words in a phrase, finds the correct word order in Strict Usoperanto and reports the total modification cost.

    Input

    The format of the input is as follows.

     N
    M0 L0
    ...
    MN-1 LN-1

    The first line contains an integer N (1 ≤ N ≤ 106). N is the number of words in a phrase.

    Each of the following N lines contains two integers Mi (1 ≤ Mi ≤ 10) and Li (-1 ≤ Li ≤ N - 1Li ≠ i) describing the i-th word (0 ≤ i ≤ N-1). Mi is the number of the letters in the word. Li specifies the modification: Li = -1 indicates it does not modify any word; otherwise it modifies the Li-th word.

    Note the first sample input below can be interpreted as the uso-beta-makka case.

    Output

    Print the total modification cost.

    Sample Input 1

    3
    3 -1
    4 0
    5 0
    

    Output for the Sample Input 1

    4
    

    Sample Input 2

    3
    10 -1
    10 0
    10 1
    

    Output for the Sample Input 2

    0
    

    Sample Input 3

    4
    1 -1
    1 0
    1 1
    1 0
    

    Output for the Sample Input 3

    1

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <vector>
    #include <queue>
    #include <algorithm>
    #include <set>
    using namespace std;
    
    #define MM(a) memset(a,0,sizeof(a))
    
    typedef long long LL;
    typedef unsigned long long ULL;
    const int maxn = 1e6+5;
    const int mod = 1000000007;
    const double eps = 1e-7;
    const double pi = 3.1415926;
    
    int M[maxn], L[maxn], cnt[maxn];
    LL fac[maxn], sz[maxn];
    vector<int> vec[maxn];
    
    inline int cmp(int x, int y)
    {
        return sz[x] < sz[y];
    }
    int n, x, y, sum;
    LL ans;
    
    void solve()
    {
        for(int i=0; i<vec[x].size(); i++)
        {
            y = vec[x][i];
            sz[x] += sz[y];
            fac[x] += sum+fac[y];
            sum += sz[y];
        }
    }
    void Get_ans()
    {
        ans = 0;
        MM(fac);
        queue<int> q;
        for(int i=0; i<n; i++)
            if(!vec[i].size())
                q.push(i);
        while(!q.empty())
        {
            x = q.front(),y;
            q.pop();
            sum = 0;
            sz[x] = M[x];
            sort(vec[x].begin(), vec[x].end(), cmp);
            solve();
            y = L[x];
            if(y != -1)
            {
                cnt[y]--;
                if (!cnt[y])
                    q.push(y);
            }
            else
                ans += fac[x];
        }
    }
    int main ()
    {
        while(~scanf("%d",&n))
        {
            MM(cnt);
            MM(vec);
            for(int i=0; i<n; i++)
            {
                scanf("%d%d",&M[i], &L[i]);
                if(L[i] != -1)
                {
                    vec[L[i]].push_back(i);
                    cnt[L[i]]++;
                }
            }
            Get_ans();
            cout<<ans<<endl;
        }
        return 0;
    }
  • 相关阅读:
    JavaScript设计模式
    《现代操作系统(中文第三版)》课后习题——第一章 绪论
    hadoop基础----hadoop理论(四)-----hadoop分布式并行计算模型MapReduce具体解释
    linux 改动rootpassword以及忘记rootpassword
    Android画图之抗锯齿 paint 和 Canvas 两种方式
    Rect参数的简易理解方式
    关于新建android项目时 appcompat_v7报错问题的一点总结
    关于seo优化的核心思想
    关于 android 读取当前手机号码
    关于 android 返回键 代码实现
  • 原文地址:https://www.cnblogs.com/chen9510/p/4852075.html
Copyright © 2011-2022 走看看