首页 > 代码库 > [luoguP1351] 联合权值(Dfs)

[luoguP1351] 联合权值(Dfs)

传送门

 

距离为2的点会产生权值,第一问,只需要在dfs的时候把一个点相邻的点都处理出来就行。

具体处理方式看代码,然而这样只处理了一遍,最后在乘2就好了。

第二问只需要处理一个点相邻的点中最大的和次大的就行。

 

——代码

技术分享
 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #define LL long long 5  6 const int MAXN = 200001, p = 10007; 7 int n, cnt; 8 int head[MAXN], to[MAXN << 1], next[MAXN << 1]; 9 LL max, tot, a[MAXN], sum[MAXN], ans[MAXN], max1[MAXN], max2[MAXN];10 bool vis[MAXN];11 12 inline int read()13 {14     int x = 0, f = 1;15     char ch = getchar();16     for(; !isdigit(ch); ch = getchar()) if(ch == -) f = -1;17     for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - 0;18     return x * f;19 }20 21 inline LL Max(LL x, LL y)22 {23     return x > y ? x : y;24 }25 26 inline void add(int x, int y)27 {28     to[cnt] = y;29     next[cnt] = head[x];30     head[x] = cnt++;31 }32 33 inline void dfs(int u)34 {35     int i, v;36     vis[u] = 1;37     for(i = head[u]; i ^ -1; i = next[i])38     {39         v = to[i];40         ans[u] = (ans[u] + sum[u] * a[v]) % p;41         sum[u] = (sum[u] + a[v]) % p;42         if(a[v] > max1[u]) max2[u] = max1[u], max1[u] = a[v];43         else if(a[v] > max2[u]) max2[u] = a[v];44         if(!vis[v]) dfs(v);45     }46 }47 48 int main()49 {50     int i, x, y;51     n = read();52     memset(head, -1, sizeof(head));53     for(i = 1; i < n; i++)54     {55         x = read();56         y = read();57         add(x, y);58         add(y, x);59     }60     for(i = 1; i <= n; i++) a[i] = read();61     dfs(1);62     for(i = 1; i <= n; i++)63     {64         tot = (tot + ans[i]) % p;65         max = Max(max, max1[i] * max2[i]);66     }67     printf("%lld %lld\n", max, (tot << 1) % p);68     return 0;69 }
View Code

 

[luoguP1351] 联合权值(Dfs)