uva10828(高斯消元)

题意:
从每个结点出发到每个后继结点的概率均相等;
当执行完一个没有后继结点后,整个过程停止;
程序从编号为1的结点开始执行;
你的任务是对于若干个查询点,求出每个结点的期望执行次数;


思路:
本来以为又是一个求普通求期望的题,像之前一样迭代求解就行了;
后来发现有无穷大的解,看了大白,发现要高斯消元;
线性代数又忘得很厉害了;代码基本照着敲的;


#include 
#include 
#include 
#include 
using namespace std;
const int maxn = 110;
const double eps = 1e-8;
typedef double Matrix[maxn][maxn];

Matrix A;
int n, d[maxn];
vector pre[maxn];
int inf[maxn];

void gauss_jordan(Matrix A, int n) {
	int i, j, k, r;
	for (i = 0; i < n; i++) {
		r = i;
		for (j = i+1; j < n; j++)
			if (fabs(A[j][i]) > fabs(A[r][i]))
				r = j;

		if (fabs(A[r][i]) < eps)
			continue;
		if (r != i)
			for (j = 0; j <= n; j++)
				swap(A[r][j], A[i][j]);

		for (k = 0; k < n; k++)
			if (i != k)
				for (j = n; j >= i; j--)
					A[k][j] -= A[k][i] / A[i][i] * A[i][j];
	}
}

int main() {
	int cas = 1;
	while (scanf("%d", &n) != EOF && n) {
		memset(d, 0, sizeof(d));
		for (int i = 0; i < n; i++)
			pre[i].clear();

		int a, b;
		while (scanf("%d%d", &a, &b) != EOF && a) {
			a--, b--;
			d[a]++;
			pre[b].push_back(a);
		}

		memset(A, 0, sizeof(A));
		for (int i = 0; i < n; i++) {
			A[i][i] = 1;
			for (int j = 0; j < pre[i].size(); j++)
				A[i][pre[i][j]] -= 1.0 / d[pre[i][j]];
			if (i == 0)
				A[i][n] = 1;
		}

		gauss_jordan(A, n);
		memset(inf, 0, sizeof(inf));
		for (int i = n-1; i >= 0; i--) {
			if (fabs(A[i][i]) < eps && fabs(A[i][n]) > eps)
				inf[i] = 1;
			for (int j = i+1; j < n; j++)
				if (fabs(A[i][j]) > eps && inf[j])
					inf[i] = 1;
		}

		int q, u;
		scanf("%d", &q);
		printf("Case #%d:\n", cas++);
		while (q--) {
			scanf("%d", &u);
			u--;
			if (inf[u])
				printf("infinity\n");
			else printf("%.3lf\n", fabs(A[u][u]) < eps ? 0.0 : A[u][n] / A[u][u]);
		}
	}
	return 0;
}


你可能感兴趣的:(数论,uva)