uva10828 - Back to Kernighan-Ritchie 约旦高斯消元

来源:互联网 发布:spark sql decimal 编辑:程序博客网 时间:2024/04/28 04:31

Problem I
Back to Kernighan-Ritchie
Input:
Standard Input

Output: Standard Output

 

Youmust have heard the name of Kernighan and Ritchie, the authors ofThe C Programming Language. While coding inC, we use differentcontrol statements and loops, such as,if-then-else,for, do-while,etc. Consider the following fragment of pseudo code:

 

 

   //execution starts here

   do {

      U;

      V;

  } while(condition);

  W;

 

 

 

 

Inthe above code, there is a bias in each conditional branch. Such codes can berepresented by control flow graphs like below:

Letthe probability of jumping from one node of the graph to any of its adjacentnodes be equal. So, in the abovecode fragment, the expected number of times U executes is 2. Inthis problem, you will be given with such a control flow graph and find theexpected number of times a node is visited starting from a specific node.

 

Input

Inputconsists of several test cases. There will be maximum 100 test cases. Each case starts with an integer: n (n ≤ 100).Here nis the number of nodes in the graph. Each node in the graph is labeled with 1 ton and execution always starts from 1. Each of the next few lines has twointegers: startand endwhich means execution may jump from node start to node end. A value of zero for start endsthis list. After this, there will be an integer q (q ≤ 100) denoting the numberof queries to come. Next q lines contain a node number for which you have to evaluate theexpected number of times the node is visited. The last test case has value ofzero for nwhich should not be processed.

 

Output

Output for each test caseshould start with “Case #i:”with next q lines containing the results of the queries in the input with threedecimal places. There can be situations where a node will be visited forever(for example, an infinite forloop). In such cases, you should print “infinity” (without the quotes). See thesample output section for details of formatting.

 

Sample Input                                  Output for Sample Input

3

1 2

2 3

2 1

0 0

3

1

2

3

3

1 2

2 3

3 1

0 0

3

3

2

1

0

Case #1:

2.000

2.000

1.000

Case #2:

infinity

infinity

infinity


 

  一开始在1,给出一个点和它能到达的点,它到那些点概率相同,求最后到所有点的期望。

  一个点的期望等于能到它的点的期望*到它的概率的和。

  假设有个点0,到1的概率是1。

  约旦高斯消元就是把其他所有行都和阶梯上的那个值相减,这样的话可以形成对角阵,不用回带。

  先构造矩阵,构造完消元后得到的矩阵。

  这种求期望的有一些性质:

  当A[i][i]=A[i][N]=0时,xi=0,因为不能到达。

  当A[i][i]=0,A[i][N]>0时,xi=INF,到不了终点,无限循环。

  若xi解唯一且有限,第i行除了A[i][i]和A[i][N]之外其它元素都为0。

  约旦消元用于唯一解的情况,这里面列的方程不一定是唯一解,可能有无数解或者无解的情况,但是对于期望来说,无数解相当于0,因为不能到达,无解的话是INF。这样也就相当于是唯一解了。

#include<iostream>#include<algorithm>#include<queue>#include<cstdio>#include<cstdlib>#include<cmath>#include<cstring>#define INF 0x3f3f3f3f#define MAXN 110#define MAXM 110#define MOD 1000000007#define MAXNODE 4*MAXN#define eps 1e-9using namespace std;typedef double Matrix[MAXN][MAXN];int N,Q,d[MAXN],inf[MAXN];Matrix A;vector<int> pre[MAXN];void gauss_jordan(Matrix A,int n){    for(int i=0;i<n;i++){        int r=i;        for(int 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(int j=0;j<=n;j++) swap(A[r][j],A[i][j]);        for(int k=0;k<n;k++) if(k!=i)            for(int j=n;j>=i;j--) A[k][j]-=A[k][i]/A[i][i]*A[i][j];    }}int main(){    freopen("in.txt","r",stdin);    int cas=0;    while(scanf("%d",&N)!=EOF&&N){        memset(d,0,sizeof(d));        for(int i=0;i<N;i++) pre[i].clear();        int u,v;        while(scanf("%d%d",&u,&v),u||v){            u--;            v--;            d[u]++;            pre[v].push_back(u);        }        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) 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;                break;            }        }        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;}


0 0
原创粉丝点击