【Codeforces】113 D. Museum

题解

我们设\(f(i,j)\)\((i,j)\)这个点期望被经过多少次
我们可以列出方程组来消元,由于终点只会被经过0次或者1次,期望就是概率
对于起点的话我们期望经过次数多加一个1
复杂度\(O(n^6)\)

代码

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <map>
//#define ivorysi
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define mo 974711
#define RG register
#define MAXN 200005
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;char c = getchar();T f = 1;
    while(c < '0' || c > '9') {
	if(c == '-') f = -1;
	c = getchar();
    }
    while(c >= '0' && c <= '9') {
	res = res * 10 + c - '0';
	c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) putchar('-'),x = -x;
    if(x >= 10) out(x / 10);
    putchar('0' + x % 10);
}
int g[25][25],ind[25];
int N,M,a,b;
db P[25],f[505][505],ans[505];
int get_id(int x,int y) {
    return (x - 1) * N + y;
}
void Guass() {
    int T = N * N;
    for(int i = 1 ; i <= T ; ++i) {
	int l = i;
	for(int j = i ; j <= T ; ++j) if(fabs(f[l][i]) < fabs(f[j][i])) l = j;
	if(l != i) {
	    for(int j = 1 ; j <= T ; ++j) swap(f[l][j],f[i][j]);
	}
	for(int j = i + 1 ; j <= T ; ++j) {
	    db t = f[j][i] / f[i][i];
	    for(int k = i ; k <= T + 1; ++k) {
		f[j][k] -= t * f[i][k];
	    }
	}
    }
    for(int i = T ; i >= 1 ; --i) {
	for(int j = i + 1 ; j <= T ; ++j) {
	    f[i][T + 1] -= f[i][j] * ans[j];
	}
	ans[i] = f[i][T + 1] / f[i][i];
    }
}
void Solve() {
    read(N);read(M);read(a);read(b);
    int u,v;
    for(int i = 1 ; i <= M ; ++i) {
	read(u);read(v);
	ind[u]++;ind[v]++;
	g[u][v] = g[v][u] = 1;
    }
    for(int i = 1 ; i <= N ; ++i) scanf("%lf",&P[i]);
    for(int i = 1 ; i <= N ; ++i) {
	for(int j = 1 ; j <= N ; ++j) {
	    int t = get_id(i,j);
	    if(i == a && j == b) f[t][N * N + 1] += 1.0;
	    f[t][t] += 1.0;
	    for(int k = 1 ; k <= N ; ++k) {
		if(k != i && !g[i][k]) continue;
		for(int h = 1 ; h <= N ; ++h) {
		    if(j != h && !g[j][h]) continue;
		    if(k == h) continue;
		    db tmp = 1.0;
		    if(i == k) tmp *= P[i];
		    else tmp *= (1 - P[k]) / ind[k];
		    if(j == h) tmp *= P[h];
		    else tmp *= (1 - P[h]) / ind[h];
		    f[t][get_id(k,h)] += -tmp;
		}
	    }
	}
    }
    Guass();
    for(int i = 1 ; i <= N ; ++i) {
	printf("%.8lf ",ans[get_id(i,i)]);
    }
    enter;
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
    return 0;
}
posted @ 2018-05-31 08:24  sigongzi  阅读(174)  评论(0编辑  收藏  举报