P1235 血缘关系

f[i][j]表示i、j的亲缘关系。
f[i][j]=(f[i][fa[j]]+f[i][mo[j]])/2或f[i][j]=(f[fa[i]][j]+f[mo[i]][j])/2
按拓扑序推一遍就好了。
听说有高精度小数。
整天邻接表不开两倍内存,还调半天调不出,跟个傻逼一样。
#include
#include
#include
#include
using namespace std;
#define rep(i,j,k) for(i=j;i<=k;++i)
#define per(i,j,k) for(i=j;i>=k;--i)
#define sqr(x) ((x)*(x))
#define G getchar()
#define LL long long
#define pll pair
#define mkp make_pair
#define X first
#define Y second
#define N 305
int n,m,fa[N],mo[N];
int he[N],ne[N<<1],to[N<<1],tot;
int q[N],in[N];
struct DATA{short dat[N];int ln;}f[N][N];
DATA operator +(DATA x,DATA y){
    x.ln=max(x.ln,y.ln);
    int i;per(i,x.ln,1)
        if((x.dat[i]+=y.dat[i])>9)++x.dat[i-1],x.dat[i]-=10;
    x.dat[0]+=y.dat[0];
    while(x.ln&&!x.dat[x.ln])--x.ln;
    return x;
}
DATA div2(DATA x){
    int i;
    rep(i,0,x.ln){
        if(x.dat[i]&1)x.dat[i+1]+=10;
        x.dat[i]>>=1;
    }
    if(x.dat[x.ln+1])x.dat[++x.ln]=5;
    return x;
}
void add(int x,int y){
    to[++tot]=y;ne[tot]=he[x];he[x]=tot;
}
int read(){
    int x=0;char ch=G;
    while(ch<48||ch>57)ch=G;
    for(;ch>47&&ch<58;ch=G)x=x*10+ch-48;
    return x;
}
void BFS(){
    int Ft=1,Rr=1,u,v,i;
    rep(i,1,n){
        if(!in[i])q[Rr++]=i;f[i][i].dat[0]=1;
    }
    while(Ft2){
        putchar('.');
        rep(i,3,x.ln)printf("%d",x.dat[i]);
    }
    puts("%");
}
int main(){
    int i,x,Q,y;
    n=read();m=read();
    while(m--){
        in[x=read()]=2;fa[x]=read();mo[x]=read();
        add(fa[x],x);add(mo[x],x);
    }
    BFS();
    for(Q=read();Q--;){
        x=read();y=read();write(f[x][y]);
    }
    return 0;
}

你可能感兴趣的:(luogu)