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
的出度为
注意判断无穷大和零的情况,为了避免这些值的干扰,可以采用高斯-约当消元来省略回代。
#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();
}
}