HDU3994(Folyd + 期望概率)
Mission Impossible
Time Limit: 30000/10000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 227 Accepted Submission(s): 106
Special Judge
Problem Description
I.M.F.(Impossible
Missions Force) is a top secret spy organization in U.S. Ethan Hunt
have serviced in this organization for many years. Now, he is retired
and serves as a spy in a big company. Although he is very excellent, he
would make mistakes. For example, last time he invaded another company
to find some programming code. When he risked his life to steal the last
few pages of the code, he found that all of the letters on them are
only “}”. His boss is very angry. So, Ethan must finish this new mission
and he needs your help.
In this new mission, Ethan successfully gets a big file in a computer and decided to send this file from this computer to his boss’s computer though the internet. We can assume the file is made of C small parts and Ethan could only send one part each unit time.
The network consists of n (n <= 200) computers, Ethan sits next to computer 1, his boss sits next to computer 2. There exists a probability p[i][j] between computer i and computer j, which means the probability of successfully transferring each part from i to j is p[i][j]. However, all of these links in the network are unidirectional (i.e. p[i][j] may be different from p[j][i]). We defined the e[i][j] as the expected time to send each part from i to j. For example, if p[i][j] = 10%, e[i][j] = 10 units.
You may find that the probability would be very tiny and the expected time could be very large since the route may be extremely long. Fortunately, Ethan knows that he has m teammates sit next to several computers. He can choose these computers as storage to shorten the transferring time. (i.e. each of the n computers could be used as node in any route, but only these m computers could be used as storages. Each attempt to send a small part, successful or unsuccessful, takes exactly one unite time, regardless of the number of links on the route.) So, he can do this mission as follows:
To satisfy his boss, Ethan must choose a route to make the total expected time from computer 1(the computer near him) to computer 2(the computer near his boss) minimum. You need to tell Ethan the minimum total expected time.
It is an impossible mission aha? Why not have a try. It’s easier than expected.
In this new mission, Ethan successfully gets a big file in a computer and decided to send this file from this computer to his boss’s computer though the internet. We can assume the file is made of C small parts and Ethan could only send one part each unit time.
The network consists of n (n <= 200) computers, Ethan sits next to computer 1, his boss sits next to computer 2. There exists a probability p[i][j] between computer i and computer j, which means the probability of successfully transferring each part from i to j is p[i][j]. However, all of these links in the network are unidirectional (i.e. p[i][j] may be different from p[j][i]). We defined the e[i][j] as the expected time to send each part from i to j. For example, if p[i][j] = 10%, e[i][j] = 10 units.
You may find that the probability would be very tiny and the expected time could be very large since the route may be extremely long. Fortunately, Ethan knows that he has m teammates sit next to several computers. He can choose these computers as storage to shorten the transferring time. (i.e. each of the n computers could be used as node in any route, but only these m computers could be used as storages. Each attempt to send a small part, successful or unsuccessful, takes exactly one unite time, regardless of the number of links on the route.) So, he can do this mission as follows:
- Choose a computer which includes the file (i.e. C parts of information) as computer u.
- Choose another computer his boss or some teammate sits next to as computer v, and then takes time to transfer the file from u to v. If any part fails to be transferred, it will be resent immediately.
- When the file is sent to his boss’s computer, the mission is finished.
To satisfy his boss, Ethan must choose a route to make the total expected time from computer 1(the computer near him) to computer 2(the computer near his boss) minimum. You need to tell Ethan the minimum total expected time.
It is an impossible mission aha? Why not have a try. It’s easier than expected.
Input
The first line contains an integer T, which means there are T test cases. Each test case is preceded by a blink line.
In each test case, you know n (2 <= n <= 200), which means the number of computers. Then an n*n matrix p(n) is following. p[i][j] means the probability of successfully transferring each part from i to j. You may assume that 0 <= p[i][j] <= 100.
Next line contains m (m <= n) means there are m computer that could serve as storage (i.e. the number of computers near Ethan, his teammates or his boss). Then a line contains m integer shows these computers. You may assume that it must contains computer 1 and computer 2.
The last line tells you there C parts in the big file. C is an integer which insure the answer is less than 1 000 000 000.
In each test case, you know n (2 <= n <= 200), which means the number of computers. Then an n*n matrix p(n) is following. p[i][j] means the probability of successfully transferring each part from i to j. You may assume that 0 <= p[i][j] <= 100.
Next line contains m (m <= n) means there are m computer that could serve as storage (i.e. the number of computers near Ethan, his teammates or his boss). Then a line contains m integer shows these computers. You may assume that it must contains computer 1 and computer 2.
The last line tells you there C parts in the big file. C is an integer which insure the answer is less than 1 000 000 000.
Output
For
each test case, you need to output a single line which contains the
minimum expected time of the transfer when Ethan chooses the best way to
finish his mission.
You’d better (not must) make the answer rounded to 7 decimal places. Your answer would be considered correct if each number has an absolute or relative error less than 10^-6.
You’d better (not must) make the answer rounded to 7 decimal places. Your answer would be considered correct if each number has an absolute or relative error less than 10^-6.
Sample Input
2
5
0 1 20 0 0
0 0 0 0 0
0 0 0 50 90
0 20 0 0 0
0 0 0 90 0
3
1 2 5
10
4
0 100 0 0
100 0 100 0
0 100 0 100
0 0 100 0
0
1
Sample Output
111.111111
1.000000
感概:这题意我真是看了3遍啊!说明我这英语真是差啊,还不知道明天四级过的了不?
题意:求将文件从起点到终点通过中转站所学需要的最小的 期望时间。先求一个文件所需要的时间。题目给出了任意两点的成功率p。我们可以通过负二项分布成功一次的期望公式1/p,求出中转站任意两点的期望(PS:这里的期望是相加的,因为从i到j的这件情况与j到k的这种情况是无关的所以可以相加)。之后求出起点到终点最小期望再乘以文件数量即得所求。
收获:1.int型 * 1.0 可以转换为 double;
2.folyd 既可以求出两点的最短路还可以求出最长路;
3.负二项分布情况出现一次的期望公式 若这个情况发生的概率为p,那么这种情况出现一次的期望为1/p。
#include <cstdio> #include <iostream> #include <cstdlib> #include <algorithm> #include <ctime> #include <cmath> #include <string> #include <cstring> #include <stack> #include <queue> #include <list> #include <vector> #include <map> #include <set> using namespace std; const int INF=0x3f3f3f3f; const double eps=1e-8; const double PI=acos(-1.0); #define maxn 500 double p[maxn][maxn]; double temp[maxn][maxn]; int sto[maxn]; int n, m; void folyd_probability() { for(int k = 1; k <= n; k++) for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) { if ((i==j) || (j==k) || (i==k)) continue; p[i][j] = max(p[i][j], p[i][k]*p[k][j]); } } void folyd_expect() { for(int k = 0; k < m; k++) for(int i = 0; i < m; i++) for(int j = 0; j < m; j++) { if ((sto[i]==sto[j]) || (sto[j]==sto[k]) || (sto[i]==sto[k])) continue; if (p[sto[i]][sto[k]]>=0 && p[sto[k]][sto[j]]>=0 && (p[sto[i]][sto[j]]<0 || p[sto[i]][sto[j]]>p[sto[i]][sto[k]]+p[sto[k]][sto[j]])) { p[sto[i]][sto[j]] = p[sto[i]][sto[k]] + p[sto[k]][sto[j]]; } } } int main() { int t; scanf("%d", &t); while(t--) { scanf("%d", &n); for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) { scanf("%lf", &p[i][j]); p[i][j] = p[i][j]/100.0; } folyd_probability(); scanf("%d", &m); for(int i = 0; i < m; i++) scanf("%d", &sto[i]); int i; for(i = 0; i < m; i++) if(sto[i] == 1) break; if(i == m) sto[m++] = 1; for(i = 0; i < m; i++) if(sto[i] == 2) break; if(i == m) sto[m++] = 2; for(i = 0; i < m; i++) for(int j = 0; j < m ;j++) { temp[sto[i]][sto[j]] = p[sto[i]][sto[j]]; if(temp[sto[i]][sto[j]] < eps) p[sto[i]][sto[j]] = -1; else p[sto[i]][sto[j]] = 1.0/temp[sto[i]][sto[j]]; } folyd_expect(); int c; scanf("%d", &c); printf("%.6lf\n", p[1][2] * c); } return 0; }