1. 程式人生 > >JZOJ 5400. 【NOIP2017提高A組模擬10.7】Repulsed

JZOJ 5400. 【NOIP2017提高A組模擬10.7】Repulsed

Description

小w 心裡的火焰就要被熄滅了。
簡便起見,假設小w 的內心是一棵n -1 條邊,n 個節點的樹。
現在你要在每個節點裡放一些個滅火器,每個節點可以放任意多個。
接下來每個節點都要被分配給一個至多k 條邊遠的滅火器,每個滅火器最多能分配給s 個節點。
至少要多少個滅火器才能讓小w 徹底死亡呢?

Solution

錯誤的貪心:時間超限80%
很顯然我們要讓滅火器放的點越高越好,且儘量讓這些滅火器放同一個點上。
這樣做有什麼好處:
①可以控制的點最多。
②讓這些滅火器放同一個點上可以確定準確的控制的範圍。
所以用堆維護目前沒有被滅掉的深度最大的點,讓他向上走k步,然後暴力刪點。
錯誤之處:
有部分滅火器控制範圍交集很大,造成巨大的浪費,顯然還可以將滅火器的控制範圍的交集變小。


正確的貪心:
考慮從底向頂貪心。
g[x][k]表示點x往下k層的沒有被滅掉的點數。f[x][k]表示利用點x往下k層的剩餘滅火器最多還能滅多少個點。
①我們應該消除距離為k且深度較大的那些點(他們的路徑不是直的),因為深度較小的可能由比x更高的點滅掉。見圖①
這裡寫圖片描述
②深度較深的點(他們的路徑是直的)必須先被滅掉,因為深度較淺的點相對較深的被滅掉的機會多。
由①、②得,
I.每次將g[x][k]f[x][0]匹配。
II.“路徑”[DIS]為k-1的也要匹配。([DIS]指dep[u]+dep[v]2dep[w],wlca(u,v))若[DIS]=k-1,則當w
=fa[w]
時,[DIS]=k+1>k,不合題意。
所以,每一次g[x][i]f[x][ki],0ik匹配,g[x][i]f[x][k1i],0ik1匹配。
每一次從兒子向父親轉移,
f[x][j]=min(n,f[x][j]+f[y][j1]),g[x][j]+=g[y][j1],(ysonx)
最後,由於點1為最高點,所以當gcd(u,v)=1時,沒有w比1深度小。
此時將g[1][i]f[1][j]相匹配,i+jk
不要忘記加上放在1的滅火器(g[1][i]≥0即還有沒被滅的點且1可以控制)。
這題告訴我們
①詢問“最少需要”可以考慮貪心
②考慮貪心的時候未必要鑽研出一個100%正確的,但是通過一些靠譜的直覺
去想一些能得出與正解非常相似的近似解的方法。

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 100010
#define LL long long
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct note{
    LL to,next;
};note edge[N*2];
LL i,j,k,l,n,m,u,v,s,ans,temp;
LL head[N],tot;
LL fa[N];
LL f[N][22],g[N][22];
LL calc(LL x){
    return x/s+((x%s)>0);
}
void lb(LL x,LL y){
    edge[++tot].to=y;
    edge[tot].next=head[x];
    head[x]=tot;
}
void dgf(LL x){
    int i;
    for(i=head[x];i;i=edge[i].next)
        if(edge[i].to!=fa[x]){
            fa[edge[i].to]=x;
            dgf(edge[i].to);
        }
}
void dg(LL x){
    int i,j;
    for(i=head[x];i;i=edge[i].next)
        if(edge[i].to!=fa[x]){
            dg(edge[i].to);
            fo(j,1,k){
                f[x][j]=min(n,f[x][j]+f[edge[i].to][j-1]);
                g[x][j]+=g[edge[i].to][j-1];
            }
        }
    g[x][0]++;
    if(g[x][k]){
        j=calc(g[x][k]);
        ans+=j;
        f[x][0]=min(n,j*s);
    }
    fo(i,0,k){
        j=min(g[x][i],f[x][k-i]);
        g[x][i]-=j,f[x][k-i]-=j;
    }
    fo(i,0,k-1){
        j=min(g[x][i],f[x][k-1-i]);
        g[x][i]-=j,f[x][k-1-i]-=j;
    }
}
int main(){
    freopen("repulsed.in","r",stdin);
    freopen("repulsed.out","w",stdout);
    scanf("%lld%lld%lld",&n,&s,&k);
    fo(i,1,n-1){
        scanf("%lld%lld",&u,&v);
        lb(u,v);lb(v,u);
    }
    ans=0;
    dgf(1);
    dg(1);
    fo(i,0,k)fd(j,k,0)
    if(i+j<=k){
        l=min(g[1][j],f[1][i]);
        g[1][j]-=l,f[1][i]-=l;
    }
    fo(i,0,k)temp+=g[1][i];
    ans+=calc(temp);
    printf("%lld",ans);
    return 0;
}

相關推薦

JZOJ 5400. NOIP2017提高A模擬10.7Repulsed

Description 小w 心裡的火焰就要被熄滅了。 簡便起見,假設小w 的內心是一棵n -1 條邊,n 個節點的樹。 現在你要在每個節點裡放一些個滅火器,每個節點可以放任意多個。 接下來每個

JZOJ 5400NOIP2017提高A模擬10.7Repulsed

DH ---------以上初三THU/PKU大爺---- Alan_cty LYD XHM HZJ ZZ ---以下是大神%-- YMW Samjia2000 werkeytom_ftd Crazy_czy WorldWide_D Yxuan

NOIP2017提高A模擬10.7Repulsed

Description: 小w 心裡的火焰就要被熄滅了。 簡便起見,假設小w 的內心是一棵n -1 條邊,n 個節點的樹。 現在你要在每個節點裡放一些個滅火器,每個節點可以放任意多個。 接下來每個節點都要被分配給一個至多k 條邊遠的滅火器,每個滅火器最多

JZOJ 5377. NOIP2017提高A模擬9.19開拓

Description Input Output Sample Input 5 50 50 10 1 10 1 20 2 10 2 20 1 30 Sam

JZOJ 5404. NOIP2017提高A模擬10.10Graph

Description 給定一張n個點m條邊的無向圖,每條邊連線兩個頂點,保證無重邊自環,不保證連通 你想在這張圖上進行若干次旅遊,每次旅遊可以任選一個點x作為起點,再走到一個與x 直接有邊相連的點y,再走到一個與y 直接有邊相連的點z 並結束本次旅遊 作

JZOJ 5439. NOIP2017提高A集訓10.31Calculate

題目 資料範圍 題解 直接求每個 ⌊ T

jzoj5350NOIP2017提高A模擬9.7陶陶摘蘋果動態規劃

description solution 題目的意思是板凳不可重疊,資料不能直接摘蘋果。對蘋果排序,對凳子按r從小到大排序。設f[i][j]表示前i個凳子,選了j個,最後一個選了i的最大貢獻,列

JZOJ 5460. NOIP2017提高A衝刺11.7士兵訓練

Description Input 第一行兩個數n,q 表示士兵數以及閱兵次數。 接下來一行n-1 個整數,第i 個整數表示士兵i+1 的直屬教官。 接下來n 行每行兩個整數i i b ,l 描述一位士兵的屬性。 接下來q 行每行一個整數i s

JZOJ 100027. NOIP2017提高A模擬7.7表示式

JZOJ 100027. 【NOIP2017提高A組模擬7.7】表示式 題目 Description Input 一行兩個整數k,p。 Output 一行一個整數表示答案。 Sample Input 1 3 Sample Output 6 D

JZOJ 100035. NOIP2017提高A模擬7.10區間

Description Input Output Sample Input sample1: 4 2 10 5 1 1 10 sample2: 1000

JZOJ5372.NOIP2017提高A模擬9.17貓鏈表+貪心+堆優化

margin targe sga gin bt5 ie8 usm shu auc x壹鼐順51比http://shequ.docin.com/txqq_cb3d1e346f 惹M3桓7O2疽http://www.docin.com/app/user/userinfo?use

JZOJ 5455NOIP2017提高A衝刺11.6拆網線

目錄: 題目: 分析: 程式碼: 題目: 傳送門 分析: 設f[i][0]f[i][0]表示在xx的子樹中,xx沒有被選擇的情況下最多有多少對點是兩兩配對的 f[

jzojs 5384. NOIP2017提高A模擬9.23四維世界

Description 眾所周知,我們常感受的世界是三維的。 Polycarp突然對四維空間產生了興趣,他想對四維空間進行一些研究。但是在此之前,他必須先對三維世界瞭解透徹。 於是Polycarp決定從零維,也就是一個點,開始他的研究。我們把一個點放在三維空間中,Polycarp把這

JZOJ5353NOIP2017提高A模擬9.9村通網最小生成樹

題目大意: 題目連結:https://jzoj.net/senior/#main/show/5353 為了加快社會主義現代化,建設新農村,農夫約(Farmer Jo)決定給農莊裡每座建築都連上網際網路,方便未來隨時隨地網購農藥。 他的農莊很大,有N 座建築,但地理位置偏僻,網路訊號很

JZOJ5354NOIP2017提高A模擬9.9導彈攔截網路流DP

題目大意: 題目連結:https://jzoj.net/senior/#main/show/5354 某國為了防禦敵國的導彈襲擊,發展出一種導彈攔截系統。 敵國的導彈形成了立體打擊,每個導彈可以抽象成一個三維空間中的點(x; y; z)。攔截系統發射的炮彈也很好地應對了這種情況,每一

JZOJ 5416NOIP2017提高A集訓10.22密碼

Description 現在身為校慶志願者的小C正在引導校友們到他們集合的教室。終於,忙了一段時間的他可以休息一會兒了。這時,旁邊一位老校友的話吸引到了他。“我後來當了一名探險家,有一次,我來到了一個地方,在正前方有一扇門,旁邊寫著一行文字:’現在給你前m個字

JZOJ 5441. NOIP2017提高A衝刺11.1序列

Description 給定一個1~n的排列x,每次你可以將x1~xi翻轉。你需要求出將序列變為升序的最小操作次數。有多組資料。 Input 第一行一個整數t表示資料組數。 每組資料第一行一個整數n,第二行n個整數x1~xn。 Output 每組

jzoj5346NOIP2017提高A模擬9.5NYG的揹包貪心

description solution 考慮貢獻為正的,顯然花費a最少先做,考慮貢獻為負的,可以將ab調轉過來,那顯然花費最少的先做,也就是b最小的先做。 code #include<

jzoj5389NOIP2017提高A模擬9.26解夢

description DYY 很善於解夢,昨晚,他夢見自己來到了一個高度發達的國度。 眾所周知,我們現在有極為常用的三級運算,+、、^。其中,a*b=a+a+a+…+a(b 個a),a^b=a

jzoj5360NOIP2017提高A模擬9.12Shorten Diameter

description 給定一棵有n 個點的樹,現要求不斷刪點直到樹的直徑<=K,求最少需要刪除的點數。 一個點可以被刪掉當且僅當該點的度數為1。 保證樹的形態為隨機生成(請勿過度解