您的位置:首页 > 大数据 > 人工智能

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 的;

④:人品要好!

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  SPFA