【HDOJ】3696 Farm Game
SPFA求最短路径。见图的时候注意逆向建图。
1 /* 3696 */ 2 #include <iostream> 3 #include <queue> 4 #include <vector> 5 #include <algorithm> 6 #include <cstdio> 7 #include <cstring> 8 #include <cmath> 9 #include <cstdlib> 10 using namespace std; 11 12 #define MAXN 10005 13 #define MAXV 10005 14 #define MAXE 50005 15 16 17 typedef struct { 18 int v, next; 19 double r; 20 } Edge_t; 21 22 const double INF = 9999999.; 23 Edge_t E[MAXE]; 24 int L, head[MAXN]; 25 double w[MAXN], p[MAXN]; 26 double rate[MAXN]; 27 bool visit[MAXN]; 28 int n, m; 29 30 void addEdge(int u, int v, double r) { 31 E[L].v = v; 32 E[L].next = head[u]; 33 E[L].r = r; 34 head[u] = L++; 35 } 36 37 void init() { 38 memset(head, -1, sizeof(int)*(n+1)); 39 L = 0; 40 } 41 42 void spfa(int u) { 43 int i, j, k, v; 44 queue<int> Q; 45 46 for (i=0; i<=n; ++i) 47 rate[i] = -INF; 48 memset(visit, false, sizeof(visit)); 49 rate[u] = 0.0; 50 visit[u] = true; 51 Q.push(u); 52 53 while (!Q.empty()) { 54 u = Q.front(); 55 Q.pop(); 56 visit[u] = false; 57 for (i=head[u]; i!=-1; i=E[i].next) { 58 v = E[i].v; 59 if (rate[v] < rate[u]+E[i].r) { 60 rate[v] = rate[u] + E[i].r; 61 if (!visit[v]) { 62 visit[v] = true; 63 Q.push(v); 64 } 65 } 66 } 67 } 68 } 69 70 int main() { 71 int i, j, k; 72 int u, v; 73 double r, ans; 74 75 #ifndef ONLINE_JUDGE 76 freopen("data.in", "r", stdin); 77 freopen("data.out", "w", stdout); 78 #endif 79 80 while (scanf("%d",&n)!=EOF && n) { 81 init(); 82 for (i=1; i<=n; ++i) { 83 scanf("%lf %lf", &p[i], &w[i]); 84 addEdge(0, i, log(p[i])); 85 } 86 scanf("%d", &m); 87 while (m--) { 88 scanf("%d %d", &k, &u); 89 --k; 90 while (k--) { 91 scanf("%lf %d", &r, &v); 92 addEdge(v, u, log(r)); 93 u = v; 94 } 95 } 96 spfa(0); 97 ans = 0.0; 98 for (i=1; i<=n; ++i) { 99 r = exp(rate[i]); 100 if (p[i] < r) 101 p[i] = r; 102 ans += p[i]*w[i]; 103 } 104 printf("%.2lf\n", ans); 105 } 106 107 return 0; 108 }