6 6 2 3 7 1 4 1 2 1 1 3 2 1 4 3 2 5 1 2 6 2
134Hintgorgeous roads are : 1-2 Value: 8 1-3 Value: 9 1-4 Value:13 1-2-6 Value:12 2-1-3 Value:11 2-1-4 Value:15 2-5 Value:3 2-6 Value:6 3-1-4 Value:16 3-1-2-6 Value:15 4-1-2-6 Value:19 5-2-6 Value:7
转题解:
一次dfs就能搞定的问题,其实没什么复杂的算法,主要难点在于统计时的一些小技巧,个人难度评价是偏难的中档题。
从任意一点开始深搜,每颗子树搜索完毕之后向上返回pair<可以延伸到该点且最后一条边与由父节点到该点的边颜色不同的gorgeous边的条数 , 所有这种边分数的总和>
每次深搜完一个子节点之后,增加的过这一点的gorgeous边的总分数为:
之前深搜的所有子节点向上返回的边数之和 * 当前子节点返回的分数 +
之前深搜的所有子节点向上返回的分数之和 * 当前子节点返回的边数 +
之前深搜的所有子节点向上返回的边数之和 * 当前子节点返回的边数 * 当前点的权
用O(n)的时间把所有的累计起来就好了什么的
才没有呢 = =
如果有当前节点分别到两个子节点的边的颜色相同的话也是不行的,
由于数据中添加了度数很大的点,理论上O(儿子数^2)的两两统计也是要被卡掉的 (希望确实的做到了
正确的做法是对所有的儿子按边的颜色排个序,然后在按这个序深搜和统计
---------------
对照着标程敲了一遍orz
一定是我树形dp的姿势不对
---------------
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <stack> #include <map> #include <set> using namespace std; const int maxn=1111111; __int64 ans,key[maxn],num[maxn],cnt[maxn]; int n; vector< pair<int,int> >tree[maxn]; void dfs(int v,int pa,int pac) { __int64 lastnum=0,nownum=0,lastcnt=0,nowcnt=0; int lastcolor=-1; num[v]=key[v]; cnt[v]=1; for (int i=0;i<tree[v].size();i++) { if (tree[v][i].second!=pa) { dfs(tree[v][i].second,v,tree[v][i].first); if (tree[v][i].first!=lastcolor) { lastnum=nownum; lastcnt=nowcnt; } lastcolor=tree[v][i].first; ans+=lastnum*cnt[tree[v][i].second]; ans+=lastcnt*num[tree[v][i].second]; ans+=lastcnt*cnt[tree[v][i].second]*key[v]; nownum+=num[tree[v][i].second]; nowcnt+=cnt[tree[v][i].second]; if (pac!=tree[v][i].first) { cnt[v]+=cnt[tree[v][i].second]; num[v]+=num[tree[v][i].second]; num[v]+=cnt[tree[v][i].second]*key[v]; } } } if (v!=1) { ans+=cnt[v]*key[pa]; ans+=num[v]; } } int main() { while (~scanf("%d",&n)) { for (int i=1;i<=n;i++) { scanf("%I64d",&key[i]); tree[i].clear(); } for (int i=1;i<=n-1;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); tree[a].push_back(make_pair(c,b)); tree[b].push_back(make_pair(c,a)); } for (int i=1;i<=n;i++) { sort(tree[i].begin(),tree[i].end()); } ans=0; dfs(1,0,-1); printf("%I64d\n",ans); } return 0; }