Sicily 1944. Exists? Or not

来源:互联网 发布:网络机顶盒app应用软件 编辑:程序博客网 时间:2024/05/19 05:05

1944. Exists? Or not

Constraints

Time Limit: 1 secs, Memory Limit: 32 MB

Description

Nowadays, after the economic reforms, our socioeconomic circumstances have been improved a lot. City population in China goes up by 7 percent per year; the rate in the big city may be even much bigger. A visible acceleration of the city is that, Shanghai today grows by 10 dwellings and 100 square meters of road every hour. We are now heading towards an urban world.
Since the population and the area of the city have increased sharply, the public transportation has become a very important problem. Then numbers of crossroads are here and there all around the city.

  For example, there were N villages in Haizhu district before. Some roads joined those villages together that exactly one path existed between any two villages. Any two roads only intersected at the village. Briefly, Haizhu district can be viewed as a tree that the villages and roads are nodes and edges of the tree. The government of Haizhu district located at a village which was called the root of the tree. The tree had M leaves (L[1],…,L[M]. In other words, each of these M villages connected to exactly one village directly). Other (N-M) nodes (including the root of the tree) each had at least two children.

In these years, a crossroad loop around the city which goes through the M villages (L[1],…,L[M]) has been built.

Assume that, L[0] is the post station which is far away from Haizhu district, but still locates on the crossroad. The postman from the post station wants to send the EMS to all the villages as soon as possible. From the statistics data, you can get the time the postman has to spend to go through each road. Now the leader of the post station wants to know whether there exists a circle (L[0]->L[1]->…->L[M]->L[0]) that the postman visits all the N villages exactly once. If so, output the minimum time the postman has to spend on the task, otherwise, just output “-1” (without quotation marks).


 

 

Input

The first line of the input is a positive integer T. T is the number of the test cases followed. Each test case contains two parts.
 The first line of the first part is a positive integer N(3N<=1000) which represents the number of the villages. After that, (N-1) lines follow. The i-th line contains three positive integers Xi(1<=Xi<=N),Yi(1<=Yi<=N),Ti(0<Ti<=1000) for the i-th edge. It means that Yi is Xi’s parent in the tree, and Ti is the time going from Xi to Yi, or from Yi to Xi.
The first line of the second part is a positive integer M(1M<N). M is the number of the leaves. And the following (M+1) lines informs you the information about the crossroad. The i-th (0iM) line followed contains three non-negative integers L[i](0<=L[i]<=N), L[i+1](0<=L[i+1]<=N), Ci(0<Ci1000). Assume that, L[0]=L[M+1]=0. The crossroad is a circle L[0]->L[1]->L[2]->…->L[M]->L[M+1]. Ci is the time going form L[i] to L[i+1], or from L[i+1] to L[i].
There would be any blank line between two test case. 

Output

The output of the program should consist of T lines, one line for each test case. The output of each test case only contains one integer. If there exists a circle satisfying the condition described above, output the minimum time to traverse all the villages from post-station and back to the post-station, the circle, otherwise, output “-1”(without quotation marks). No redundant spaces are needed.

 

 

Hint:

The feasible circle is 0->2->1->3->0, the total time is 4 


 

 

Sample Input

132 1 13 1 120 2 12 3 13 0 1

Sample Output

4

// Problem#: 1944// Submission#: 3589469// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/// All Copyright reserved by Informatic Lab of Sun Yat-sen University#include <stdio.h>#include <string.h>const int MAXN = 1010;long N, M;long link[MAXN][MAXN];long parent[MAXN];long t[MAXN];long c[MAXN];long nChild[MAXN];long firstLeaf[MAXN];long ans[MAXN][3];long cc;void input() {    long i, j, x, y, z, temp;    memset(parent, 0, sizeof(parent));    memset(t, 0, sizeof(t));    scanf("%ld", &N);    for (i = 1; i < N; i++) {        scanf("%ld", &x);        scanf("%ld%ld", parent + x, t + x);    }    memset(c, 0, sizeof(c));    memset(link, 0, sizeof(link));    memset(nChild, 0, sizeof(nChild));    memset(firstLeaf, 0, sizeof(firstLeaf));    cc = 0;    scanf("%ld", &M);    for (i = 0; i <= M; i++) {        scanf("%ld%ld%ld", &x, &y, &z);        if (!i || i == M) cc += z;        firstLeaf[y] = y;        c[y] = z;        if (i < M) {            temp = y;            while (parent[temp]) {                if (!nChild[parent[temp]]) firstLeaf[parent[temp]] = y;                link[parent[temp]][nChild[parent[temp]]++] = temp;                if (nChild[parent[temp]] > 1) break;                temp = parent[temp];            }        }    }    for (i = 0; i <= N; i++)        for (j = 0; j < 3; j++)            ans[i][j] = -1;}long findRoot() {    long i;    for (i = 1; i <= N; i++) if (!parent[i]) break;    return i;}long Travel(long root, long flag) {    long i, k, temp;    if (!nChild[root]) {ans[root][flag] = 0; return 0;}    if (ans[root][flag] >= 0) return ans[root][flag];    switch(flag) {    case 0:        for (k = 1; k < nChild[root]; k++) {            temp = t[link[root][k - 1]] + t[link[root][k]];            for (i = 0; i < k - 1; i++)                temp += c[firstLeaf[link[root][i + 1]]] + Travel(link[root][i], 0);            temp += Travel(link[root][k - 1], 2);            temp += Travel(link[root][k], 1);            for (i = k + 1; i < nChild[root]; i++)                temp += c[firstLeaf[link[root][i]]] + Travel(link[root][i], 0);            if (ans[root][0] < 0) ans[root][0] = temp;            else if (temp < ans[root][0]) ans[root][0] = temp;        }        break;    case 1:        ans[root][1] = t[link[root][0]];        ans[root][1] += Travel(link[root][0], 1);        for (i = 1; i < nChild[root]; i++)            ans[root][1] += c[firstLeaf[link[root][i]]] + Travel(link[root][i], 0);        break;    case 2:        ans[root][2] = t[link[root][nChild[root] - 1]];        for (i = 1; i < nChild[root]; i++)            ans[root][2] += c[firstLeaf[link[root][i]]] + Travel(link[root][i - 1], 0);        ans[root][2] += Travel(link[root][nChild[root] - 1], 2);        break;    }    return ans[root][flag];}int main() {    long T, root, answer;    scanf("%ld", &T);    while (T--) {        input();        root = findRoot();        answer = cc + Travel(root, 0);        printf("%ld\n", answer);    }    return 0;}                                 


0 0