bzoj 1415 聪聪和可可 (期望dp)

来源:互联网 发布:opensuse和ubuntu 编辑:程序博客网 时间:2024/05/17 05:09

这里写图片描述

题解

这道题目是我的第一道期望dp……期望dp高深莫测令人恐惧……

代码

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int INF = 0x73f3f3f;struct Edge {    int v, next;} e[2010];int N, E, s, m, num = 0, head[2010];void add(int u, int v) {    num ++;    e[num].v = v;    e[num].next = head[u];    head[u] = num;}int q[1010], dis[1010], vis[1010], state[10010], road[1010][1010];void spfa(int s) {    memset(dis, INF, sizeof(dis));    int h = 0, tail = 1;    state[1] = s, vis[s] = true, dis[s] = 0;    while(h < tail) {        h ++;        int u = state[h]; vis[u] = false;        for(int i = head[u]; i; i = e[i].next) {            int v = e[i].v;            if(dis[v] > dis[u] + 1) {                dis[v] = dis[u] + 1;                if(! vis[v]) {                    tail ++;                    state[tail] = v;                    vis[v] = true;                }            }        }    }}double f[1010][1010];double dfs(int s, int m) {    if(f[s][m]) return f[s][m];    if(s == m) return 0;    if(road[road[s][m]][m] == m || road[s][m] == m) return 1.0;    double ans = dfs(road[road[s][m]][m], m);//敌动我不动     for(int i = head[m]; i; i = e[i].next) {        int v = e[i].v;        ans += dfs(road[road[s][m]][m], v);    }//敌动我也动     return f[s][m] = ans / (q[m] + 1) + 1;//每种概率是相等的直接同除 }int main() {    scanf("%d %d", &N, &E);    scanf("%d %d", &s, &m);    while(E --) {        int u, v;        scanf("%d %d", &u, &v);        q[u] ++, q[v] ++;        add(u, v); add(v, u);    }    for(int i = 1; i <= N; i ++) {        spfa(i);        for(int j = 1; j <= N; j ++) {            int mmax = INF;             for(int k = head[j]; k; k = e[k].next) {                int v = e[k].v;                if(dis[v] < mmax || (dis[v] == mmax && v < road[j][i])) {//小的走小的;相同的走标号小的                    mmax = dis[v];                    road[j][i] = v;                }            }        }    }    printf("%0.3lf", dfs(s, m));}
原创粉丝点击