Cow Relays

Description

For their physical fitness program, N (2 ≤ N ≤ 1,000,000) cows have decided to run a relay race using the T (2 ≤ T ≤ 100) cow trails throughout the pasture.

Each trail connects two different intersections (1 ≤ I1i ≤ 1,000; 1 ≤ I2i ≤ 1,000), each of which is the termination for at least two trails. The cows know the lengthi of each trail (1 ≤ lengthi  ≤ 1,000), the two intersections the trail connects, and they know that no two intersections are directly connected by two different trails. The trails form a structure known mathematically as a graph.

To run the relay, the N cows position themselves at various intersections (some intersections might have more than one cow). They must position themselves properly so that they can hand off the baton cow-by-cow and end up at the proper finishing place.

Write a program to help position the cows. Find the shortest path that connects the starting intersection (S) and the ending intersection (E) and traverses exactly N cow trails.

Input

* Line 1: Four space-separated integers: N, T, S, and E
* Lines 2..T+1: Line i+1 describes trail i with three space-separated integers: lengthi , I1i , and I2i

Output

* Line 1: A single integer that is the shortest distance from intersection S to intersection E that traverses exactly N cow trails.

Sample Input

`2 6 6 411 4 64 4 88 4 96 6 82 6 93 8 9`

Sample Output

```10题意：求经过n条路的最短路。
#include <stdio.h>#include <stdlib.h>#define inf 1 << 30#define maxn 101#define Min(a, b) a < b ? a : bint hash[maxn*10], g[maxn], num, ksp[maxn][maxn], len[maxn];void set(){    int i;    num = 0;    for (i = 1; i < maxn; i++)    {        hash[i] = 0;    }}int makeHash(int a){    if (!hash[a])    {        hash[a] = ++num;    }    return hash[a];}int main(){    int n, t, s, e, h, i, j, k, u, v, w;    while (scanf("%d%d%d%d", &n, &t, &s, &e) != EOF)    {        set();        for (h = 0; h < 23; h++)        {            for (i = 1; i < maxn; i++)            {                for (j = 1; j < maxn; j++)                {                    ksp[h][i][j] = inf;                }            }        }        while (t--)        {            scanf("%d%d%d", &w, &u, &v);            u = makeHash(u), v = makeHash(v);            ksp[u][v] = ksp[v][u] = Min(w, ksp[v][u]);        }        s = makeHash(s), e = makeHash(e);        for (h = 1; (1 << h) <= n; h++)//求出i到j经过2的h次方路径的最短路         {            for (i = 1; i <= num; i++)            {                for (j = 1; j <= num; j++)                {                    if (ksp[h-1][i][j] < inf)                    {                        for(k = 1; k <= num; k++)                        {                            if (ksp[h][i][k] > ksp[h-1][i][j] + ksp[h-1][j][k])                            {                                ksp[h][i][k] = ksp[h-1][i][j] + ksp[h-1][j][k];                            }                                                    }                    }                }            }                }        for (i = 1; i <= num; i++)        {            len[i] = inf;        }        len[s] = 0;        for (h = 0, k = 0; (1 << h) <= n; h++)//组合s到其他节点经过n条路的最短路         {            if (n & (1 << h))//枚举n的二进制上有1的。             {                for (i = 1; i <= num; i++)                {                    len[i][k ^ 1] = inf;                }                for (i = 1; i <= num; i++)                {                    if (len[i][k] < inf)//这里要判断一下，因为1<<30再加上1<<30就超出int了                     {                        for (j = 1; j <= num; j++)                        {                            len[j][k ^ 1] = Min(len[j][k ^1], len[i][k] + ksp[h][i][j]);                        }                    }                }                k = k ^ 1;            }        }        printf("%d\n", len[e][k]);    }    system("pause");    return 0;}
```