标签:
题意:给一个树,边有颜色,点有权值。满足路径上没有两个相邻边同色的路径是好的路径,求好的路径的(路径上的点的权值和)的总和
思路:
边权排序,从任意一点开始深搜,每颗子树搜索完毕之后向上返回pair<可以延伸到该点且最后一条边与由父节点到该点的边颜色不同的gorgeous边的条数 , 所有这种边分数的总和>
每次深搜完一个子节点之后,增加的过这一点的gorgeous边的总分数为:
之前深搜的所有子节点向上返回的边数之和 * 当前子节点返回的分数 +
之前深搜的所有子节点向上返回的分数之和 * 当前子节点返回的边数 +
之前深搜的所有子节点向上返回的边数之和 * 当前子节点返回的边数 * 当前点的权
代码:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int MAX_N = 300007; typedef long long ll; struct Edge { int u, v, w, nxt; Edge () { } Edge (int _u, int _v ,int _w, int _n) { u = _u; v = _v; w = _w; nxt = _n; } bool operator < (const Edge &rhs) const { return w < rhs.w; } }; int n; int head[MAX_N], ecnt; ll ans, val[MAX_N], num[MAX_N], sum[MAX_N]; Edge T[MAX_N], G[MAX_N << 1]; void Clear() { ecnt = ans = 0; memset(head, -1, sizeof head); memset(num, 0, sizeof num); memset(sum, 0, sizeof sum); } void add(int u, int v, int w) { G[ecnt] = Edge(u, v, w, head[u]); head[u] = ecnt++; } void dfs(int u, int fa, int col) { ll tot = 0, tot1 = 0, tot2 = 0, k = 0, k1 = 0, k2 = 0; int nowCol = 0; for (int i = head[u]; ~i; i = G[i].nxt) { int v = G[i].v, w = G[i].w; if (v == fa) continue; dfs(v, u, w); if (w != col) tot += sum[v], k += num[v]; if (w != nowCol) { tot1 += tot2; k1 += k2; tot2 = sum[v], k2 = num[v]; nowCol = w; } else tot2 += sum[v], k2 += num[v]; ans += sum[v] * (k1 + 1) + tot1 * num[v] + val[u] * (k1 + 1) * num[v]; } num[u] = ++k, sum[u] = val[u] * k + tot; } template <class T> inline bool rd(T &ret) { char c; int sgn; if(c = getchar() , c == EOF) return false; while(c != ‘-‘ && (c < ‘0‘ || c > ‘9‘)) c = getchar(); sgn = (c == ‘-‘) ? -1 : 1; ret = (c == ‘-‘) ? 0 : (c - ‘0‘); while(c = getchar(), c >= ‘0‘ && c <= ‘9‘) ret = ret * 10 + (c - ‘0‘); ret *= sgn; return true; } int main() { while (1 == scanf("%d", &n)) { for (int i = 1; i <= n; ++i) rd(val[i]); for (int i = 0; i + 1 < n; ++i) { rd(T[i].u), rd(T[i].v), rd(T[i].w); } sort(T, T + n - 1); Clear(); for (int i = 0; i + 1 < n; ++i) { add(T[i].u, T[i].v, T[i].w); add(T[i].v, T[i].u, T[i].w); } dfs(1, -1, -1); printf("%I64d\n", ans); } return 0; }
标签:
原文地址:http://www.cnblogs.com/Rojo/p/4718323.html