MZ Training 2014 #8 F题
2014-10-13 21:31
549 查看
这个题啊。。。先上题吧。
[Description]
有n个点,m条边,现在要用这些来建立一颗以1号点为根的圣诞树
对于每一个点有一个点权w, 每条边也有一个边权c
对于一棵树的代价,我们这样计算(具体可以看看样例解释):
代价=每个点的代价和
一个点的代价=这个点及它的所有后代节点点权之和乘以指向它的边的边权。
[Input]
第一行一个整数T,表示T组数据
对于每组数据,第一行两个整数n和m
第二行n个整数wi,每个点的点权
接下来m行,每行三个整数a b c,表示a和b之间有一条边权为c的无向边
[Output]
对于每组数据输出一行,即最小的代价Total
如果不能组成一棵树,则输出 “ No Answer ”
[Sample Input]
2
2 1
1 1
1 2 15
7 7
200 10 20 30 40 50 60
1 2 1
2 3 3
2 4 2
3 5 4
3 7 2
3 6 3
1 5 9
[Sample Output]
15
1210
[Hint]
0 <= n, m <= 50000
所有的数都小于216
对于样例2,我们不用1 5 9这一条边,那么建出来的树如图所示
其代价计算
1号点:(200 + 10 + 20 + 30 + 40 + 50 + 60) * 0 = 0
2号点:(10 + 20 + 30 + 40 + 50 + 60) * 1 = 210
3号点:(20 + 40 + 50 + 60) * 3 = 510
4号点:30 * 2 = 60
5号点:40 * 4 = 160
6号点:60 * 2 = 120
7号点:50 * 3 = 150
Total = 0 + 210 + 510 + 60 + 160 + 120 + 150 = 1210
那么这个问题是可以简化的。
对于指向某个节点的一条边,它的后代必然会参与计算这条边。所以某个点的点权就会被从根(1)到它的所有边计算一次。为什么不以每个子节点为计算单位呢?
这TM不就是对每个点求最短路吗?
好了,答案出来了,就是这个。
n为点的个数;dis[i]为1到这个点的最短路;w[i]为这个点的点权。
注意:
①:判断无解(出现不连通)
②:最坏情况答案 49999*65536=3276734464,所以dis[]数组要开long long;
③:初值必须够大,但要注意:不能用memset,因为它不能赋超int的初值;
也不能这样写:for(int i=1;i<=n;i++) dis[i]=4000000000;
而要这样写:for(int i=1;i<=n;i++) dis[i]=4000000000LL;
加的“LL”表示这个常量是long long 的;
④:人品要好!
[Description]
有n个点,m条边,现在要用这些来建立一颗以1号点为根的圣诞树
对于每一个点有一个点权w, 每条边也有一个边权c
对于一棵树的代价,我们这样计算(具体可以看看样例解释):
代价=每个点的代价和
一个点的代价=这个点及它的所有后代节点点权之和乘以指向它的边的边权。
[Input]
第一行一个整数T,表示T组数据
对于每组数据,第一行两个整数n和m
第二行n个整数wi,每个点的点权
接下来m行,每行三个整数a b c,表示a和b之间有一条边权为c的无向边
[Output]
对于每组数据输出一行,即最小的代价Total
如果不能组成一棵树,则输出 “ No Answer ”
[Sample Input]
2
2 1
1 1
1 2 15
7 7
200 10 20 30 40 50 60
1 2 1
2 3 3
2 4 2
3 5 4
3 7 2
3 6 3
1 5 9
[Sample Output]
15
1210
[Hint]
0 <= n, m <= 50000
所有的数都小于216
对于样例2,我们不用1 5 9这一条边,那么建出来的树如图所示
其代价计算
1号点:(200 + 10 + 20 + 30 + 40 + 50 + 60) * 0 = 0
2号点:(10 + 20 + 30 + 40 + 50 + 60) * 1 = 210
3号点:(20 + 40 + 50 + 60) * 3 = 510
4号点:30 * 2 = 60
5号点:40 * 4 = 160
6号点:60 * 2 = 120
7号点:50 * 3 = 150
Total = 0 + 210 + 510 + 60 + 160 + 120 + 150 = 1210
那么这个问题是可以简化的。
对于指向某个节点的一条边,它的后代必然会参与计算这条边。所以某个点的点权就会被从根(1)到它的所有边计算一次。为什么不以每个子节点为计算单位呢?
这TM不就是对每个点求最短路吗?
好了,答案出来了,就是这个。
n为点的个数;dis[i]为1到这个点的最短路;w[i]为这个点的点权。
注意:
①:判断无解(出现不连通)
②:最坏情况答案 49999*65536=3276734464,所以dis[]数组要开long long;
③:初值必须够大,但要注意:不能用memset,因为它不能赋超int的初值;
也不能这样写:for(int i=1;i<=n;i++) dis[i]=4000000000;
而要这样写:for(int i=1;i<=n;i++) dis[i]=4000000000LL;
加的“LL”表示这个常量是long long 的;
④:人品要好!
相关文章推荐
- MZ Training 2014 #5 E题
- MZ Training 2014 #4 B题
- 斯坦福iOS7 2013-2014秋Assignment 6的一种答案 #8
- MZ Training 2014 #6 A题
- MZ Training 2014 #6 B题
- MZ Training 2014 #6 C题
- NENU Summer Training 2014 #8
- MZ Training 2014 #6 D题
- MZ Training 2014 #5 D题
- GnuTLS 3.3.3 remote memory corruption(CVE-2014-3466)
- 大数乘法的几种算法分析及比较(2014腾讯南京笔试题)
- SQL Server 2014 Installation Error - Wait on the Database Engine Recovery Handle Failed
- 学习CMM的object detection 2014 CVPR(一)
- CodeForces 500B Good Bye 2014 New Year Permutation
- MyEclipse-pro-2014GA 下载
- 2014 10.1放假安排,2014.10.1放假安排
- 谷歌百度脸书IBM,人工智能四巨头2014盘点
- 【NOIP2014】联合权值
- 2014网站设计风格趋势
- 落魄的2014