zoukankan      html  css  js  c++  java
  • UVa 10828 Back to Kernighan-Ritchie 高斯消元+概率DP

    题目来源:UVa 10828 Back to Kernighan-Ritchie

    题意:从1開始 每次等概率从一个点到和他相邻的点 有向 走到不能走停止 求停止时每一个点的期望

    思路:写出方程消元 方程有唯一解 多解 无解的情况 有环 一直再环里无法停止算无穷大 从1不能到的点期望为0

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    #include <cmath>
    using namespace std;
    const int maxn = 110;
    const double eps = 1e-8;
    typedef double Matrix[maxn][maxn];
    vector <int> G[maxn];
    int d[maxn];
    int inf[maxn];
    void gauss_jordan(Matrix A, int n)
    {
    	int i, j, r, k;
    	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)
    		{
    			if(r != i)
    				for(j = 0; j <= n; j++)
    					swap(A[r][j], A[i][j]);
    			for(k = 0; k < n; k++)
    			{
    				if(k != i)
    				{
    					for(j = n; j >= i ; j--)
    					{
    						A[k][j] -= A[k][i]/A[i][i] * A[i][j];
    					}
    				}
    			}
    		}
    	}
    }
    Matrix A;
    int main()
    {
    	int cas = 1;
    	int n;
    	while(scanf("%d", &n) && n)
    	{
    		memset(d, 0, sizeof(d));
    		for(int i = 0; i < n; i++)
    			G[i].clear();
    		int u, v;
    		while(scanf("%d %d", &u, &v) && (u||v))
    		{
    			u--;
    			v--;
    			G[v].push_back(u);
    			d[u]++;
    		}
    		memset(A, 0, sizeof(A));
    		for(int i = 0; i < n; i++)
    		{
    			A[i][i] = 1;
    			for(int j = 0; j < G[i].size(); j++)
    				A[i][G[i][j]] -= 1.0 / d[G[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;
    		scanf("%d", &q);
    		printf("Case #%d:
    ", cas++);
    		while(q--)
    		{
    			int x;
    			scanf("%d", &x);
    			x--;
    			if(inf[x])
    			{
    				puts("infinity");
    				continue;
    			}
    			if(fabs(A[x][x]) < eps)
    			{
    				puts("0.000");
    				continue;
    			}
    			printf("%.3lf
    ", A[x][n] / A[x][x]);
    		}
    	}
    	return 0;
    }


  • 相关阅读:
    视图&索引&序列
    PL/SQL语言基础
    C#实现递归矩阵连乘(动态规划的递归自顶向下,非递归自地向上)
    JS 第五课
    请问,小丽的鞋子到底是什么颜色的?
    用10!来回顾 PL/SQL语言基础 && 标准异常名
    SELECT 查询—子查询
    备份和恢复
    JS 第六课
    Linux学习之二Linux系统的目录结构
  • 原文地址:https://www.cnblogs.com/jzssuanfa/p/6781976.html
Copyright © 2011-2022 走看看