【洛谷P1351】聯合權值
阿新 • • 發佈:2018-12-09
連結
這個題讓我們求得是最大聯合權值和聯合權值之和。
先來討論較簡單的,聯合權值之和。
當需要求兩個點之間的某些關係時,往往可以將其轉化成一個點的問題。
比如這個題,就可以通過列舉中間點,通過一些式子算出答案(如下圖)
指出的那一個點,以它為中點的答案之和就是它周圍一圈的點所有組合的答案之和,這一點很好想到。
列舉的話是不太好的,如果是一個200000的菊花圖,就完美的TLE了。
所以很明顯可以O(1)算出來。
一個點的答案,就是(與它相關點的和的平方-平方和)/2。
模擬一下的話:
然後?然後就完了啊。
有了這個思路以後,最大值和次大值順帶搞一搞就好了。
要注意有兩種情況:
1.當前權值大於這個點範圍內的最大值:m2=m1,m1=w;
2.當前權值大於次大值小於最大值:m2=w;
其他的隨緣就好了。
(我的程式碼好樸素啊)
#include<iostream> #include<cstdio> #include<string> #include<cstring> #include<algorithm> #define maxn 200005 #define mod 10007 using namespace std; int n,x,y; int sqr[maxn],sum[maxn],w[maxn],head[maxn]; int max1[maxn],max2[maxn]; struct node{ int y,nxt; }e[maxn*2]; int tot=0; inline void ad(int x,int y){ ++tot; e[tot].y=y;e[tot].nxt=head[x];head[x]=tot; } inline void dfs(int u,int fa) { max1[u]=w[fa]; int y; for(int i=head[u];i;i=e[i].nxt){ y=e[i].y; if(y!=fa){ if(w[y]>=max1[u]){ max2[u]=max1[u]; max1[u]=w[y]; } else if(w[y]<max1[u]&&w[y]>max2[u])max2[u]=w[y]; } sqr[u]=(sqr[u]+(w[y]*w[y])%mod)%mod; sum[u]=(sum[u]+w[y])%mod; if(y!=fa)dfs(y,u); } } int main() { scanf("%d",&n); for(int i=1;i<n;++i){ scanf("%d%d",&x,&y); ad(x,y);ad(y,x); } for(int i=1;i<=n;++i) scanf("%d",&w[i]); dfs(1,0); int ans=0,ans2=0; for(int i=1;i<=n;++i) ans=(ans+(sum[i]*sum[i]-sqr[i])%mod)%mod, ans2=max(ans2,max1[i]*max2[i]); printf("%d %d",ans2,ans); }