http://acm.hdu.edu.cn/showproblem.php?pid=4035
Get:
1, the first inference is not a tree. In fact, all the feeling figure, both the look at the number of sides = = count-1 is not set
2, sometimes, I tell the child to distinguish the tree is still necessary, that is, only when the DFS, when the number of references to a parent node to indicate the number of parameters
3, must pay attention to the probability of DP to the accuracy of the very high need to start writing 1e-8,wa several, changed 1e-10 AC
4, note that the denominator is 0 possible when adding inference
A very specific explanation: http://blog.csdn.net/morgan_xww/article/details/6776947
The code written directly by the formula is:
#include <cstdio> #include <cstring> #include <algorithm> #include <string> #include < iostream> #include <iomanip> #include <cmath> #include <map> #include <set> #include < queue>using namespace std; #define LS (RT) Rt*2#define RS (RT) Rt*2+1#define ll long long#define ull unsigned long long#de Fine Rep (I,s,e) for (int. i=s;i<e;i++) #define REPE (i,s,e) for (int i=s;i<=e;i++) #define CL (A, B) memset (A,b,sizeof (A )) #define IN (s) freopen (S, "R", stdin) #define OUT (s) freopen (S, "w", stdout) const LL ll_inf = ((ull) ( -1)) >>1;const Double EPS = 1e-10;const int INF = 100000000;const int maxn = 10000+100;VECTOR<INT>G[MAXN];d ouble K[MAXN],E[MAXN];d o Uble a[maxn],b[maxn],c[maxn];int n;bool Sea (int i, int fa) {if (g[i].size () = = 1 && fa!=-1)//leaf node {a[ I]=k[i]; C[i]=b[i]=1.0-k[i]-e[i]; return true; }//non-leaf node, at this time the descendants of the non-leaf node have traversed double aa=0.0,bb=0.0,cc=0.0; for (int j=0;j<g[i].size (); j + +) {if(G[i][j] = = FA) continue; if (!sea (g[i][j],i)) return 0; AA+=A[G[I][J]]; BB+=B[G[I][J]]; CC+=C[G[I][J]]; } int m=g[i].size (); A[i]= (k[i]+ (1-k[i]-e[i])/M*AA)/(n (1.0-k[i]-e[i])/M*BB); B[i]= (1.0-k[i]-e[i])/m/(1.0-(1.0-k[i]-e[i])/M*BB); C[i]= ((1.0-k[i]-e[i]) + (1.0-k[i]-e[i])/M*CC)/(1.0-(1.0-k[i]-e[i])/M*BB); return true;} int main () {int ncase,u,v,ic=0; scanf ("%d", &ncase); while (ncase--) {scanf ("%d", &n); for (int i=1;i<=n;i++) g[i].clear (); for (int i=1;i<n;i++) {scanf ("%d%d", &u,&v); G[u].push_back (v); G[v].push_back (U); } for (int i=1;i<=n;i++) {scanf ("%lf%lf", &k[i],&e[i]); k[i]/=100.0; e[i]/=100.0; } printf ("Case%d:", ++ic); if (Sea (1,-1) && fabs (1.0-a[1]) >eps) printf ("%.6lf\n", c[1]/(1.0-a[1])); else printf ("ImpossIble\n "); } return 0;}
Of course, the better writing is still a puzzle.
#include <cstdio> #include <iostream> #include <vector> #include <cmath> using namespace std ; const int MAXN = 10000 + 5; Double E[MAXN], K[MAXN]; Double A[MAXN], B[MAXN], C[MAXN]; Vector<int> V[MAXN]; BOOL Search (int i, int fa) {if (v[i].size () = = 1 && fa! = 1) {A[i] = K[i]; B[i] = 1-k[i]-e[i]; C[i] = 1-k[i]-e[i]; return true; } A[i] = K[i]; B[i] = (1-k[i]-e[i])/v[i].size (); C[i] = 1-k[i]-e[i]; Double tmp = 0; for (int j = 0; J < (int) v[i].size (); j + +) {if (v[i][j] = = FA) continue; if (!search (v[i][j], i)) return false; A[i] + = A[v[i][j]] * b[i]; C[i] + = C[v[i][j]] * b[i]; TMP + = B[v[i][j]] * b[i]; } if (Fabs (tmp-1) < 1e-10) return false; A[i]/= 1-tmp; B[i]/= 1-tmp; C[i]/= 1-tmp; return true; } int main () {inT NC, N, s, t; CIN >> NC; for (int CA = 1; CA <= NC; ca++) {cin >> n; for (int i = 1; I <= n; i++) v[i].clear (); for (int i = 1; i < n; i++) {cin >> s >> t; V[s].push_back (t); V[t].push_back (s); } for (int i = 1; I <= n; i++) {cin >> k[i] >> e[i]; K[i]/= 100.0; E[i]/= 100.0; } cout << "case" << CA << ":"; if (search (1,-1) && fabs (1-a[1]) > 1e-10) cout << c[1]/(1-a[1]) << Endl; else cout << "impossible" << Endl; } return 0; }
Copyright notice: This article blog original articles, blogs, without consent, may not be reproduced.
HDU 4035 possibilities DP Chengdu online game