Bzoj 2878: [noi2012] lost amusement park

Source: Internet
Author: User

Question Link

Question:

A weighted undirected graph with n points n-1 or n edges is provided. Start from each point and never go through another point. What is the mathematical expectation of the path length?

N <= 100000. In the figure, there is at most one ring, and the length of the Ring cannot exceed 20.

Question:

First, consider a tree:

First, take a node as the root node (for example, point 1) and create a tree chart.

The expected length of the Child tree where I goes is f [I], and the child nodes of I are S1, S2 ...... SK.

If d [I] = Σ (F [SJ] + edge (I, SJ) is set, F [I] = d [I]/K.

If P [I] is set to I as the expected length of the start point, P [1] = f [1] and Du [I] is the degree of node I.

Run the DFS again. If Y is a subnode of X, p [x] has been calculated.

The expected contribution of node y to X is other, other = (P [x] * Du [x]-edge (x, y)-f [x]). /(Du [x]-1) + edge (x, y)

P [y] = (Other + d [y])/du [y]

In this way, the P values of all vertices can be calculated through two DFS operations.

However, this question may be a base ring tree.

First, you can find this ring through DFS. If you remove this ring, it is the forest composed of some sub-trees.

First, use the aforementioned tree-like motion gauge method to process these sub-trees and find D and F.

Then we noticed that there were few points on the ring, so we calculated each point on the ring as the starting point.

For point X on the ring, set calc_pre (X) to the expected length from X to the left side of the ring, calc_nxt (X) the expected length obtained from the right side of the X-ring.

If SX is X.

Then P [x] = (Σ (F [SX] + edge (x, SX) + calc_pre (x) + calc_nxt (x)/du (X ).

Among them, calc_pre and calc_nxt can be calculated based on the complexity of O (number of points on the ring.

So we can calculate the p of all points in DFS again.

Ans = (Σ p [I])/n

/**************************************************************    Problem: 2878    User: zrts    Language: C++    Result: Accepted    Time:588 ms    Memory:10748 kb****************************************************************/ #include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<vector>//by zrt//problem:using namespace std;typedef long long LL;const int inf(0x3f3f3f3f);const double eps(1e-9);bool oncircle[100005];int du[100005];int fa[100005];int H[100005],X[200005],P[200005],tot;double E[200005];inline void add(int x,int y,int z){//add an edge    P[++tot]=y;X[tot]=H[x];H[x]=tot;E[tot]=z;}int n,m;double F[100005];//for son Edouble D[100005];// F * |son|double p[100005];// ansint num[100005];// |son|int pre[100005];double wpre[100005];bool type;void treedp1(int x){//Dp the tree first    for(int i=H[x];i;i=X[i]){        if(P[i]==fa[x]||oncircle[P[i]]) continue;        fa[P[i]]=x;        treedp1(P[i]);        D[x]+=F[P[i]]+E[i];num[x]++;    }    if(num[x])    F[x]=D[x]/num[x];    else F[x]=0;}void treedp2(int x,double edge){//Dp the tree second | calc the P    double other;    if(!fa[fa[x]]) {        if(!type){            if(num[fa[x]]>1) other=(p[fa[x]]*(num[fa[x]]+0)-edge-F[x])/(num[fa[x]]-1)+edge;            else other=edge;        }else{            other=(p[fa[x]]*(num[fa[x]]+2)-edge-F[x])/(num[fa[x]]+1)+edge;        }    }    else other=(p[fa[x]]*(num[fa[x]]+1)-edge-F[x])/num[fa[x]]+edge;         p[x]=(other+D[x])/(num[x]+1);    for(int i=H[x];i;i=X[i]){        if(P[i]==fa[x]||oncircle[P[i]]) continue;        treedp2(P[i],E[i]);    }}vector<int> circle;bool ok;int nxt[100005];double wnxt[100005];void findcircle(int x,int fa){    for(int i=H[x];i;i=X[i]){        if(P[i]==fa) continue;        if(pre[P[i]]){            ok=1;            int k=x;            pre[P[i]]=x;            wpre[P[i]]=E[i];            do{                oncircle[k]=1;                circle.push_back(k);                k=pre[k];            }while(k!=P[i]);            oncircle[k]=1;            circle.push_back(k);        }else{            pre[P[i]]=x;wpre[P[i]]=E[i];            findcircle(P[i],x);            if(ok) return;        }    }}double calc_nxt(int now,int end){    double ret=wnxt[now];    now=nxt[now];    int extra=0;    if(nxt[now]!=end) ret+=calc_nxt(now,end)/(du[now]-1);    else extra=-1;    for(int i=H[now];i;i=X[i]){        if(oncircle[P[i]]) continue;        ret+=(E[i]+F[P[i]])/(du[now]-1+extra);    }    return ret;}double calc_pre(int now,int end){    double ret=wpre[now];    now=pre[now];    int extra=0;    if(pre[now]!=end) ret+=calc_pre(now,end)/(du[now]-1);    else extra=-1;    for(int i=H[now];i;i=X[i]){        if(oncircle[P[i]]) continue;        ret+=(E[i]+F[P[i]])/(du[now]-1+extra);    }    return ret;}int main(){// the main function    #ifdef LOCAL    freopen("in.txt","r",stdin);    freopen("out.txt","w",stdout);    #endif    scanf("%d%d",&n,&m);    for(int i=0,x,y,z;i<m;i++){        scanf("%d%d%d",&x,&y,&z);        du[x]++;        du[y]++;        add(x,y,z);        add(y,x,z);    }    if(m==n-1){        treedp1(1);        p[1]=F[1];        for(int i=H[1];i;i=X[i]){            treedp2(P[i],E[i]);        }        double ans=0;        for(int i=1;i<=n;i++){             ans+=p[i];        }        printf("%.5f\n",ans/n);    }else{        type=1;        pre[1]=-1;        findcircle(1,-1);        for(int now=0;now<circle.size();now++){            nxt[pre[circle[now]]]=circle[now];            wnxt[pre[circle[now]]]=wpre[circle[now]];        }        for(int now=0;now<circle.size();now++){            for(int i=H[circle[now]];i;i=X[i]){                if(oncircle[P[i]]) continue;                treedp1(P[i]);                p[circle[now]]+=(F[P[i]]+E[i])/du[circle[now]];                num[circle[now]]++;            }        }        for(int now=0;now<circle.size();now++){            p[circle[now]]+=(calc_pre(circle[now],circle[now])+calc_nxt(circle[now],circle[now]))/du[circle[now]];        }        for(int now=0;now<circle.size();now++){            for(int i=H[circle[now]];i;i=X[i]){                if(oncircle[P[i]]) continue;                fa[P[i]]=circle[now];                treedp2(P[i],E[i]);            }        }        double ans=0;        for(int i=1;i<=n;i++){            ans+=p[i];        }        printf("%.5f\n",ans/n);    }    return 0;}

Bzoj 2878: [noi2012] lost amusement park

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.