POJ 1202 Family 概率,DP,高精 难度:2

时间:2022-08-31 11:43:02

http://poj.org/problem?id=1202

难度集中在输出格式上,因为输出格式所以是高精度

递推式:

血缘肯定只有从双亲传到儿子的,所以,设f,m为双亲,son为儿子,
p[i][j]为i和j之间的血缘关系,p[j][i]=p[i][j]

则:

p[son][f]=p[son][m]=0.5+0.5*p[f][m]

对于兄弟和其他不是双亲的节点j,则有

p[son][j]=0.5*(p[f][j]+p[m][j])

另外:http://swerc.up.pt/2002/Data/有数据

代码交了好几次都是RE,突然交了一次居然AC了

import java.math.BigDecimal;
import java.util.*; class mes{
int son,nxt;
mes(){son=nxt=0;}
}
public class Main {
final static int maxn=650;
static int head[];
static BigDecimal p[][];
static mes s[];
static int fa[][];
static int n,k,m;
static int vis[];
static int que[]; static void addedge(int f,int t,int ind)
{
s[ind].nxt=head[f];
s[ind].son=t;
head[f]=ind;
}
static Scanner scanner;
static void init()
{
for(int i=0;i<maxn;i++){
head[i]=-1;
}
scanner = new Scanner(System.in);
n=scanner.nextInt();
k=scanner.nextInt();
for(int i=0; i<k; i++)
{
int son,f,m;
son=scanner.nextInt();
f=scanner.nextInt();
m=scanner.nextInt();
addedge(f,son,2*i);
addedge(m,son,2*i+1);
fa[son][0]=f;
fa[son][1]=m;
}
for(int i=1; i<=n; i++)
{
p[i][i]=BigDecimal.ONE;
}
} static void calc()
{
int front=0,tail=0;
final BigDecimal mul=BigDecimal.valueOf(0.5);
for(int i=1; i<=n; i++)
{
if(fa[i][0]==0&&fa[i][1]==0&&vis[i]==0)
{
que[tail++]=i;
vis[i]=1;
}
}
while(tail!=front)
{
int tp=que[front];front++;
vis[tp]=2;
int f=fa[tp][0],m=fa[tp][1];
if(f!=0&&m!=0)
{
p[tp][f]=p[tp][m]=p[f][tp]=p[m][tp]=(p[f][m].add(BigDecimal.ONE)).multiply(mul);
for(int i=1; i<=n; i++)
{
if(i!=f&&i!=tp&&i!=m)
{
p[i][tp]=p[i][tp].add((p[i][m].add(p[i][f])).multiply(mul));
p[tp][i]=p[i][tp];
}
}
} for(int sp=head[tp]; sp!=-1; sp=s[sp].nxt)
{
int son=s[sp].son;
if(vis[son]!=0)continue;
if(vis[fa[son][0]]==2&&vis[fa[son][1]]==2)
{
que[tail++]=son;
vis[son]=1;
}
}
}
}
static void show()
{
m=scanner.nextInt();
for(int i=0; i<m; i++)
{
int f,t;
f=scanner.nextInt();
t=scanner.nextInt();
String ans = p[t][f].multiply(BigDecimal.valueOf(100)).toPlainString();
if(ans.indexOf(".")>0&&ans.indexOf(".")<ans.length()){
while(ans.length()>1&&ans.endsWith("0")){
ans=ans.substring(0,ans.length()-1);
}
}
if(ans.endsWith(".")&&ans.length()>1)ans=ans.substring(0,ans.length()-1);
System.out.println(ans+"%");
}
}
public static void main(String[] args) {
head=new int[maxn];
p=new BigDecimal[maxn][maxn];
s=new mes[2*maxn];
fa=new int[maxn][2];
que=new int[maxn];
vis = new int[maxn];
for(int i=0;i<maxn;i++){p[i]=new BigDecimal[maxn];s[i]=new mes();fa[i]=new int[2];}
for(int i=0;i<maxn;i++){for(int j=0;j<maxn;j++){p[i][j]=BigDecimal.ZERO;}}
init();
calc();
show();
}
}