uva10828 Back to Kernighan-Ritchie

175 篇文章 0 订阅
137 篇文章 0 订阅

You must have heard the name of Kernighan and Ritchie , the authors of
The C Programming Language . While coding in C , we use different
control statements and loops, such as, if-then-else , for , do-while ,
etc. Consider the following fragment of pseudo code: //execution
starts here do f U ; V ; g while( condition ); W; In the above code,
there is a bias in each conditional branch. Such codes can be
represented by control ow graphs like below: Let the probability of
jumping from one node of the graph to any of its adjacent nodes be
equal. So, in the above code fragment, the expected number of times U
executes is 2. In this problem, you will be given with such a control
ow graph and nd the expected number of times a node is visited
starting from a speci c node. Input Input consists of several test
cases. There will be maximum 100 test cases. Each case starts with an
integer: n ( n 100). Here n is the number of nodes in the graph.
Each node in the graph is labeled with 1 to n and execution always
starts from 1. Each of the next few lines has two integers: start and
end which means execution may jump from node start to node end. A
value of zero for start ends this list. After this, there will be an
integer q ( q 100) denoting the number of queries to come. Next q
lines contain a node number for which you have to evaluate the
expected number of times the node is visited. The last test case has
value of zero for n which should not be processed. Output Output for
each test case should start with Case # i : ’ with next q lines
containing the results of the queries in the input with three decimal
places. There can be situations where a node will be visited forever
(for example, an in nite for loop). In such cases, you should print `
infinity ’ (without the quotes). See the sample output section for
details of formatting.

设点 i 的出度为du[i],期望执行次数为 f[i] 。可以列出方程

f[i]=j>if[j]du[j]

注意判断无穷大和零的情况,为了避免这些值的干扰,可以采用高斯-约当消元来省略回代。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define M(a) memset(a,0,sizeof(a))
const double eps=1e-8;
double a[110][110];
bool inf[110],zero[110];
int n,du[110];
vector<int> pre[110];
void init()
{
    int i,j,u,v;
    M(pre);
    M(du);
    M(a);
    while (scanf("%d%d",&u,&v)&&u)
    {
        pre[--v].push_back(--u);
        du[u]++;
    }
    for (i=0;i<n;i++)
    {
        a[i][i]=1;
        for (j=0;j<pre[i].size();j++)
          a[i][v=pre[i][j]]-=1.0/du[v];
        if (!i) a[i][n]=1;
    }
}
void solve()
{
    int i,j,k,p;
    for (i=0;i<n;i++)
    {
        p=i;
        for (j=i+1;j<n;j++)
          if (fabs(a[j][i])>fabs(a[p][i])) p=j;
        if (p!=i)
          for (j=0;j<n;j++)
            swap(a[i][j],a[p][j]);
        if (fabs(a[i][i])<eps) continue;
        for (j=0;j<n;j++)
          if (j!=i)
            for (k=n;k>=i;k--)
              a[j][k]-=a[i][k]*a[j][i]/a[i][i];
    }
}
void out()
{
    M(inf);
    M(zero);
    int i,j,q,u;
    for (i=n-1;i>=0;i--)
      if (fabs(a[i][i])<eps)
      {
        if (fabs(a[i][n])<eps) zero[i]=1;
        else inf[i]=1;
      }
      else
        for (j=i+1;j<n&&!inf[i];j++)
          if (fabs(a[i][j])>eps&&inf[j])
            inf[i]=1;
    scanf("%d",&q);
    while (q--)
    {
        scanf("%d",&u);
        if (inf[--u]) printf("infinity\n");
        else if (zero[u]) printf("0.000\n");
        else printf("%.3f\n",a[u][n]/a[u][u]);
    }
}
int main()
{
    int K=0;
    while (scanf("%d",&n)&&n)
    {
        init();
        solve();
        printf("Case #%d:\n",++K);
        out();
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值