[图论]Bright Network Hub(最短路+动态规划)

Bright Network Hub


Time Limit:5sMemory limit:32M
Accepted Submit:61Total Submit:255

Microhard company has just invented a brandly new speeding up device called Bright Network Hub(BNH). The BNH can be installed on the fibers between two nodes. When a BNH works, all the information going through this fiber will cost half of the original time. If n BNHs are installed on the same fiber, the speed for going through this fiber will be 2^n times faster.

In order to improve the speed of campus network, students in FZU are planning to buy some BNHs. Since they don't have enough money, they can only afford to buy m BNHs. Given the network of n nodes, you are to install these m BNHs on the proper lines, so that the time needed from node 1 to node n can be minimized.

In the above network the minimal time needed from 1 to 5 is 44ms. Now if you have 2 BNHs. Installing both of them on the fiber 1-2, the time from 1 to 2 will become 8.5ms. However, the optimal scheme is to install them on 1-3 and 3-5.

Input

There are multiple test cases. The first line of each case contains two integers n and m (1<=n<=50, 1<=m<=10). The following n lines contains the network graph in adjcent matrix. There are n real numbers each line, representing the needed time in millisecond. If there is no fiber between two nodes, the corresponding entry will be 0. And it is guaranteed that there will always be a path from 1 to n.

Output

For each case, output only one line containing the minimal time from 1 to n, accurate to two fractional digits.

Sample Input

5 2
0 34 24 0 0
34 0 10 12 0
24 10 0 16 20
0 12 16 0 30
0 0 20 30 0

Sample Output

22.00
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main()
{
    int i, j, k, u;
    int fiber, bnh;
    double node[52][52][12];
    double path[52][12], min;
    int visit[52];
    int p;

    while (scanf("%d %d", &fiber, &bnh) != EOF)
    {
        for (i = 1; i <= fiber; ++i)
        {
            for (j = 1; j <= fiber; ++j)
            {
                scanf("%lf", &node[i][j][0]);
                for (k = 1; k <= bnh; ++k)
                    node[i][j][k] = node[i][j][k - 1] * 0.5;
            }
        }

        /* Dijkstra alg. */
        for (k = 0; k <= bnh; ++k)
        {
            memset(visit, 0, sizeof(visit));
            
            for (i = 1; i <= fiber; ++i)
                path[i][k] = node[1][i][k];
            visit[1] = 1;

            for (i = 1; i < fiber; ++i)
            {
                min = 1000000000;
                for (j = 1; j <= fiber; ++j)
                {
                    if ((visit[j] == 0) && (path[j][k] != 0) && (path[j][k] < min))
                    {
                        min = path[j][k];
                        p = j;
                    }
                }

                if (min == 1000000000)
                    break;

                visit[p] = 1;
                for (j = 1; j <= fiber; ++j)
                {
                    for (u = 0; u <= k; ++u)
                    {
                        if ((node[p][j][k - u] != 0) && ((path[j][k] == 0) || (path[j][k] > path[p][u] + node[p][j][k - u])))
                            path[j][k] = path[p][u] + node[p][j][k - u];
                    }
                }
            }
        }

        printf("%.2lf\n", path[fiber][bnh]);
    }
    
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值