sicily1784. Road Toll

Constraints

Time Limit: 1 secs, Memory Limit: 64 MB

Description

There are N cities, identified from 1 to N. There is one and only one road between every two cities. When somebody goes through a road, he must pay the toll. The toll is calculated like this: when he takes M money with him, he ought to pay M × r. The r may be different for different roads, and r is a real number between 0 and 1(inclusive). Now you want to go from city A to city B, how much money can be left? Suppose the money you took is 1 at the beginning.

Input

The first line contains an integer T, indicating the number of cases.

For each case, the first contains the three integer number N(3 ≤ N ≤ 100), A and B(1 ≤ A,B ≤ N). The following lines contain the N × N symmetric matrix, where each element shows the toll rate r from one city to another. You can suppose that all the elements of the matrix will be real numbers between 0 and 1(inclusive) and the diagonal of the matrix is always 0.

Output

For each case, output a real number rounded to 2 decimals, indicating the most money you can keep at last when you go from A to B.

Sample Input

1
3 1 3
0.00 0.10 0.20
0.10 0.00 0.10
0.30 0.20 0.00

Sample Output

0.81


最短路的变形的题目,有固定的算法 简单题。

#include <iostream>
#include <cstring>
#include <stdio.h>
#include <queue>
#include <stack>
#include <set>
#include <iomanip>
#include <cmath>
using namespace std;

struct Node
{
    int index;
    float remin;
    friend bool operator<(Node n1, Node n2)
    {
        return n1.remin > n2.remin;
    }
};

int main()
{
    int t;
    scanf("%d", &t);
    int n, a, b;
    float adj[109][109];
    while (t --)
    {
        scanf("%d%d%d", &n, &a, &b);
        for (int i = 1; i <= n; ++ i)
        {
            for (int j = 1; j <= n; ++ j)
            {
                scanf("%f", &adj[i][j]);
            }
        }
        Node ant[n + 1];
        for (int i = 1; i <= n; ++ i)
        {
            ant[i].index = i;
            ant[i].remin = 0;
        }
        int know[109];
        memset(know, 0, sizeof(know));
        ant[a].remin = 1;
        set<Node> s;
        s.insert(ant[a]);
        while (1)
        {
            set<Node>::iterator it = s.begin();
            int tem = (*it).index;
            float temp = (*it).remin;
            know[tem] = 1;
            if (tem == b)
            {
                printf("%.2f\n", temp);
                break;
            }
            s.erase(s.begin(), s.end());
            for (int i = 1; i <= n; ++ i)
            {
                if (i == tem)
                {
                    continue;
                }
                else if (know[i] == 0)
                {
                    float atemp = temp - temp * adj[tem][i];
                    if (ant[i].remin < atemp)
                    {
                        ant[i].remin = atemp;
                    }
                    s.insert(ant[i]);
                }
            }
        }
    }
}                                 




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值