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]);
}
}
}
}
}