Big Christmas Tree
Description
Christmas
is coming to KCM city. Suby the loyal civilian in KCM city is preparing
a big neat Christmas tree. The simple structure of the tree is shown in
right picture.
The tree can be represented as a collection of numbered nodes and some edges. The nodes are numbered 1 through n.
The root is always numbered 1. Every node in the tree has its weight.
The weights can be different from each other. Also the shape of every
available edge between two nodes is different, so the unit price of
each edge is different. Because of a technical difficulty, price of an
edge will be (sum of weights of all descendant nodes) × (unit price of
the edge).
Suby wants to minimize the cost of whole tree among
all possible choices. Also he wants to use all nodes because he wants a
large tree. So he decided to ask you for helping solve this task by
find the minimum cost.
Input
The input consists of T test cases. The number of test cases T is given in the first line of the input file. Each test case consists of several lines. Two numbers v, e (0 ≤ v, e ≤ 50000) are given in the first line of each test case. On the next line, v positive integers wi indicating the weights of v nodes are given in one line. On the following e lines, each line contain three positive integers a, b, c indicating the edge which is able to connect two nodes a and b, and unit price c.
All numbers in input are less than 216.
Output
For
each test case, output an integer indicating the minimum possible cost
for the tree in one line. If there is no way to build a Christmas tree,
print “No Answer” in one line.
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
題意:一個(gè)邊在樹(shù)中的代價(jià)是它的子樹(shù)中所有節(jié)點(diǎn)權(quán)值的和乘以該邊的權(quán)值。求連接所有點(diǎn)的最小代價(jià)。
分析:每個(gè)點(diǎn)到根貢獻(xiàn)了路徑的的權(quán)值和乘以改點(diǎn)權(quán)值。這就成了最短路的題了。
本來(lái)以為用個(gè)棧存點(diǎn)就行,沒(méi)想到超時(shí)。
最后把它改為循環(huán)隊(duì)列。
#include <stdio.h>
#include <stdlib.h>
#define maxn 70001
#define Min(a, b) a < b ? a : b
long long inf = (long long)1 << 62;
struct
{
int v, next, w;
}edge[maxn * 2];
int g[maxn], visit[maxn], stack[maxn * 2], val[maxn];
long long dis[maxn];
void set(int n)
{
for (int i = 1; i <= n; i++)
{
g[i] = -1;
}
}
void spfa(int n, int s)
{
int i, u, w, v;
for (i = 1; i <= n; i++)
{
dis[i] = inf, visit[i] = 0;
}
int top = 1, head = 0;
stack[top] = s;
dis[s] = 0;
while (head != top)
{
head = (head + 1) % maxn;
u = stack[head];
visit[u] = 0;
for (i = g[u]; i != -1; i = edge[i].next)
{
v = edge[i].v, w = edge[i].w;
if (dis[v] > dis[u] + w)
{
dis[v] = dis[u] + w;
if (!visit[v])
{
top = (top + 1) % maxn;
stack[top] = v;
visit[v] = 1;
}
}
}
}
long long ans;
for (i = 1, ans = 0; i <= n; i++)
{
if (dis[i] == inf)
{
break;
}
ans += dis[i] * val[i];
}
if (i != n + 1)
{
printf("No Answer\n");
}
else
{
printf("%lld\n", ans);
}
}
int main()
{
int t, n, m, i, th, u, v, w, min;
scanf("%d", &t);
while (t--)
{
scanf("%d%d", &n, &m);
set(n);
g[1] = -1;//處理點(diǎn)數(shù)為0時(shí)的初始化一個(gè)根,沒(méi)初始化會(huì)超時(shí)
for (i = 1; i <= n; i++)
{
scanf("%d", &val[i]);
}
th = 0;
while (m--)
{
scanf("%d%d%d", &u, &v, &w);
edge[th].v = v, edge[th].w = w, edge[th].next = g[u], g[u] = th++;
edge[th].v = u, edge[th].w = w, edge[th].next = g[v], g[v] = th++;
}
spfa(n, 1);
}
system("pause");
return 0;
}