1. 程式人生 > >“浪潮杯”第九屆山東省ACM大學生程式設計競賽 D-Dance

“浪潮杯”第九屆山東省ACM大學生程式設計競賽 D-Dance

來源:牛客網

題意:

在根節點為0的樹上(編號:0,1,2...n)。一條邊上有兩個值 poweri ,numi,相當於網路流:poweri相當於路上的cost,numi相當於容量,相當於匯點為0,源點為所有葉子節點,求最大費用。

樣例:

7
0 100 0
1 2 3
2 2 5
1 5 1
2 1 3
3 2 4
4 3 2

輸出:

33

分析:想到可以貪心優先分配路上總power最大的葉子節點,然後求路上最小值mi,ans加上power*mi,然後把路徑上的num都減去最小值mi,重複下去。然後用樹鏈剖分維護就行。(看別人程式碼不用樹鏈刨分直接修改也能過)。

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
using namespace std;
typedef long long int ll;
const int inf = 1e9;
const int maxn = 100000;
int n,son[maxn+5],sz[maxn+5],fa[maxn+5],top[maxn+5],tid[maxn+5],Rank[maxn+5],tim,dep[maxn+5];
int num[maxn+5],power[maxn+5],cost[maxn+5],st[maxn+5];
int mi[maxn*4],add[maxn*4];
vector<int>g[maxn+5];
void dfs1(int x,int f)
{
    sz[x] = 1, fa[x] = f, son[x]=-1;
    int len = g[x].size();
    for(int i=0; i<len; i++)
    {
        int y = g[x][i];
        if(y==f) continue;
        dep[y] = dep[x] + 1;
        cost[y]+=cost[x]+power[y];
        dfs1(y,x);
        sz[x]+=sz[y];
        if(son[x]==-1||sz[son[x]]<sz[y]) son[x] = y;
    }
}
void dfs2(int x,int tp)
{
    top[x] = tp;
    tid[x] = ++tim;
    Rank[tim] = x;
    if(son[x]!=-1) dfs2(son[x],tp);
    for(int i=0,len=g[x].size(); i<len; i++)
    {
        int y = g[x][i];
        if(y!=son[x]&&y!=fa[x])
            dfs2(y,y);
    }
}
void pushup(int o)
{
    mi[o] = min(mi[o*2],mi[o*2+1]);
}
void build(int o,int l,int r)
{
    add[o]=0;
    if(l==r)
    {
        mi[o] = num[Rank[l]];
        return;
    }
    int mid = (l+r)>>1;
    build(o*2,l,mid);
    build(o*2+1,mid+1,r);
    pushup(o);
}
void pushdown(int o)
{
    if(add[o]!=0)
    {
        int ls = o*2, rs = o*2+1;
        mi[ls]+=add[o], mi[rs]+=add[o];
        add[ls]+=add[o], add[rs]+=add[o];
        add[o] = 0;
    }
}
int query(int o,int l,int r,int L,int R)
{
    if(L<=l&&r<=R) return mi[o];
    int mid = (l+r)>>1;
    pushdown(o);
    if(R<=mid) return query(o*2,l,mid,L,R);
    else
    {
        if(mid<L) return query(o*2+1,mid+1,r,L,R);
        return min(query(o*2,l,mid,L,R),query(o*2+1,mid+1,r,L,R));
    }
}
void updata(int o,int l,int r,int L,int R,int ad)
{
    if(L<=l&&r<=R)
    {
        mi[o]+=ad;
        add[o]+=ad;
    }
    else
    {
        pushdown(o);
        int mid = (l+r)>>1;
        if(R<=mid) updata(o*2,l,mid,L,R,ad);
        else
        {
            if(mid<L) updata(o*2+1,mid+1,r,L,R,ad);
            else
            {
                updata(o*2,l,mid,L,R,ad);
                updata(o*2+1,mid+1,r,L,R,ad);
            }
        }
        pushup(o);
    }
}
int Find(int u,int v)
{
    int f1 = top[u], f2 = top[v], tmp = inf;
    while(f1!=f2)
    {
        if(dep[f1]<dep[f2]) swap(f1,f2), swap(u,v);
        tmp = min(tmp,query(1,1,tim,tid[f1],tid[u]));
        u = fa[f1];
        f1 = top[u];
    }
    if(u==v) return tmp;
    if(dep[u]>dep[v]) swap(u,v);
    return min(tmp,query(1,1,tim,tid[son[u]],tid[v]));
}
void Updata(int va,int vb,int ad)
{
    int f1 = top[va], f2 = top[vb];
    while (f1 != f2)
    {
        if (dep[f1] < dep[f2])
        {
            swap(f1, f2);
            swap(va, vb);
        }
        updata(1,1,tim,tid[f1],tid[va],ad);
        va = fa[f1];
        f1 = top[va];
    }
    if (va == vb) return;
    if (dep[va] > dep[vb]) swap(va, vb);
    updata(1, 1, tim, tid[son[va]], tid[vb],ad);
}
bool cmp(int x,int y)
{
    return cost[x] > cost[y];
}
int main()
{
    scanf("%d",&n);
    for(int i=0; i<=n; i++) g[i].clear();
    for(int i=1,f; i<=n; i++)
    {
        scanf("%d %d %d",&f,&num[i],&power[i]);
        g[f].push_back(i);
    }
    dep[0] = 0;
    dfs1(0,-1);
    tim = -1;
    dfs2(0,0);
    build(1,1,tim);
    int cnt = 0;
    for(int i=1; i<=n; i++) if(g[i].size()==0) st[++cnt] = i;
    sort(st+1,st+cnt+1,cmp);
    ll ans = 0;
    for(int i=1; i<=cnt; i++)
    {
        int x = st[i];
        int w = Find(x,0);
        if(w<=0) continue;
        ans += cost[x]*1ll*w;
        Updata(x,0,-w);
    }
    printf("%lld\n",ans);
    return 0;
}

相關推薦

浪潮九屆山東省ACM大學生程式設計競賽 D-Dance

來源:牛客網題意:在根節點為0的樹上(編號:0,1,2...n)。一條邊上有兩個值 poweri ,numi,相當於網路流:poweri相當於路上的cost,numi相當於容量,相當於匯點為0,源點為所有葉子節點,求最大費用。樣例:70 100 01 2 32 2 51 5

浪潮九屆山東省ACM大學生程式設計競賽重現賽 題解

點選轉到(牛客網) 1.思路:       給定兩個字串,假設是ELLY與KRIS,E到K是6,L到R是6,當第二個L到I時,L是比I大的,此時L就要繞到Z,從Z到A,再從A開始到I,這樣長度就是23,Y到S同理,長度是20;這樣找完之後序列長度之和就是6 +6+23

浪潮九屆山東省ACM大學生程式設計競賽重現賽 G game (尼姆博弈)

題目描述 Alice and Bob are playing a stone game. There are n piles of stones. In each turn, a player can remove some stones from a pile (th

浪潮山東省八屆ACM大學生程式設計競賽I

Fascinated with the computer games, Gabriel even forgets to study. Now she needs to finish her homework, and there is an easy problem: f(n)= She is requir

浪潮山東省八屆ACM大學生程式設計競賽 J

sell goods whose price with order as -1, 5, 6, 6, the total benefit would be -1*1 + 5*2 + 6*3 + 6*4 = 51. 01 #include <iostream>

浪潮九屆山東acm程式設計賽C題 Cities

題目描述 There are n cities in Byteland, and the i city has a value a . The cost of building a bidirectional road between two cities is the

2015年山東省六屆ACM大學生程式設計競賽-B-Lowest Unique Price

Link: http://www.sdutacm.org/sdutoj/problem.php?action=showproblem&problemid=3252 Lowest Unique Price Time Limit: 1000ms

SDUT 3258 Square Number(2015年山東省六屆ACM大學生程式設計競賽)

Square Number Time Limit: 1000ms   Memory limit: 65536K  有疑問?點這裡^_^ 題目描述 In mathematics,

山東省七屆ACM大學生程式設計競賽 總結

很惋惜的一場比賽,比賽前我想了很多個結局,可能是銀牌中等,銀牌末尾,要是運氣好的可能能混一個金牌回來。。但是銀首這個真的是超乎我意料之外。。。 開始比賽的不久我就看到了K題,一個作為簽到題的存在,開始習慣性的先敲輸入輸出。寫完輸入輸出之後感覺沒有比較好寫的思路

Fruit Ninja II(山東省三屆ACM大學生程式設計競賽

Have you ever played a popular game named "Fruit Ninja"? Fruit Ninja (known as Fruit Ninja HD on the iPad and Fruit Ninja THD for Nvidia Tegra 2 based A

山東省三屆ACM大學生程式設計競賽 Fruit Ninja I(01揹包)

01揹包 加上vector的運用,貪心sort排序 #include <stdio.h> #include <vector> #include <string.h>

2018山東省ACM大學生程式設計競賽B.Bullet

In GGO, a world dominated by gun and steel, players are fighting for the honor of being the strongest gunmen. Player Shino is a sniper, and her aimed shot

2017河南省十屆ACM大學生程式設計競賽總結

河南第十屆大學生程式設計競賽總結             比賽過程隊友部落格有記錄:http://blog.csdn.net/dreamNYC/article/details/71417450             主要就總結下這次比賽的感受:                     我們隊雖然和

浪潮山東省九屆ACM大學生程式設計競賽

目錄 題目描述 輸入描述: 輸出描述: 輸入 輸出 解析: 程式碼: 題目描述 輸入描述: 輸出描述: 輸入 輸出 題目描述 輸入描述: 輸出描述: 輸入 輸出 題目描述 輸入描述: 輸出描述: 輸入 輸出 題

浪潮山東省九屆ACM大學生程式設計競賽 F Four-tuples (容斥原理)

題目連結 比賽時推了好久的容斥,結果推錯了,過了樣例就交了,然後A了。後來才知道這題有bug。菜啊。 題意:給定四個區間(li,ri)(li,ri)(閉區間),求一個四元組(x1,x2,x3,x4)(x1,x2,x3,x4),滿足xixi在區間(li,ri)

2018九屆山東省ACM省賽

        作為一名大一打鐵的萌新,初到濟南的時候很激動啊,到了之後的中午發的鴨腿飯,很好吃,主辦方在吐槽水的問題後也很貼心的送來了礦泉水,唯一不爽的是忘記自己出去了之後沒流量了,結果下了個王者榮耀跟師哥師姐們開黑燒了100多話費(尬         下午熱身賽,發揮還

山東省第一屆ACM大學生程式設計競賽 Phone Number 字典樹

Phone Number Time Limit: 1000ms   Memory limit: 65536K  有疑問?點這裡^_^ 題目描述 We know that if a phone number A is another phone number B’s

2010年山東省第一屆ACM大學生程式設計競賽——Greatest Number

Greatest Number 題目意思:給你一串數,任取四個,可以重複,求最大值,但不能超過m。 可以先將任意兩個數相加,然後再二分查詢求出符合題意的最大值即可。 #include<i

2018九屆山東省ACM——B Bullet

Bullet Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description In GGO, a world dominated by gun and steel, players are figh

[2010山東省第一屆ACM大學生程式設計競賽]——Hello World!

Hello World!題目描述 We know that Ivan gives Saya three problems to solve (Problem F), and this is the first problem. “We need a programmer t