題目鏈接:點擊查看
題目大意:給出一棵 n 個點組成的樹,每條邊上都有邊權,現在可以進行數次操作,每次操作可以選擇一條路徑,使得路徑上的權值減一,問最少需要進行多少次操作才能使得所有的邊權變為 0 ,輸出這個操作次數,再給出 m 次詢問,每次詢問會修改一條邊權,每次需要回答修改邊權后的答案
題目分析:讀完題的第一感覺是樹形dp然后用樹剖+線段樹優化,事實證明確實可以寫,但我不會寫
講一下官方題解的做法吧,非常需要思維,首先需要將邊權轉換為點權,對于每次操作選取一條路徑然后將其路徑上的邊權減一,對應過來就是將兩個端點遍歷一次,這樣問題就轉換為了,將所有邊權變為 0 時,令每個端點被訪問的次數之和最小
對于每個點計算貢獻,就會發現有兩種情況:假設 mmax 為與當前點相連的所有邊中,權值最大的邊權,sum 為與當前點相連的所有邊權之和
mmax <=?( sum - mmax ):此時肯定有一種匹配方法使得邊權兩兩互相匹配,換句話說,當前點不需要作為端點與其他端點形成路徑,只需要作為中間點被經過就好,這樣的貢獻就是 sum%2 ,因為如果 sum 為奇數的話,會有一條邊權失配,那么只能由該點作為端點一次mmax > ( sum - mmax ):此時如果其余所有的邊都與 mmax 匹配的話,最終還是會剩下 mmax - ( sum - mmax ) 的邊權失配,那么需要當前點作為端點這么多次才行
對于每次修改,只需要維護一個 multiset 實時計算貢獻就好了
最后的答案記得除以 2 ,因為當邊權映射給點權后,是一條邊權對應著兩個端點,我們維護的 ans 是最少點的貢獻,轉換為邊的貢獻當然應該除以 2 了
代碼:
?
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
#include<unordered_map>
using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=1e5+100;multiset<int>st[N];LL sum[N];int x[N],y[N],w[N];void del(int p)
{int x=::x[p],y=::y[p],w=::w[p];st[x].erase(st[x].find(w));st[y].erase(st[y].find(w));sum[x]-=w;sum[y]-=w;
}void add(int p)
{int x=::x[p],y=::y[p],w=::w[p];st[x].insert(w);st[y].insert(w);sum[x]+=w;sum[y]+=w;
}LL cal(int p)
{int mmax=*st[p].rbegin();if(mmax*2>sum[p])return mmax*2-sum[p];elsereturn sum[p]&1;
}int main()
{
#ifndef ONLINE_JUDGE
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
#endif
// ios::sync_with_stdio(false);int n,m;scanf("%d%d",&n,&m);for(int i=1;i<n;i++){scanf("%d%d%d",x+i,y+i,w+i);add(i);}LL ans=0;for(int i=1;i<=n;i++)ans+=cal(i);printf("%lld\n",ans/2);while(m--){int pos,val;scanf("%d%d",&pos,&val);ans-=cal(x[pos])+cal(y[pos]);del(pos);w[pos]=val;add(pos);ans+=cal(x[pos])+cal(y[pos]);printf("%lld\n",ans/2);}return 0;
}
?
總結
以上是生活随笔為你收集整理的牛客多校10 - Decrement on the Tree(边权转点权+思维)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。