【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
", ans);
105     }
106     
107     return 0;
108 }
原文地址:https://www.cnblogs.com/bombe1013/p/4346546.html