zoukankan      html  css  js  c++  java
  • NOI2012 迷失游乐园

    http://www.lydsy.com/JudgeOnline/problem.php?id=2878

    比较容易的概率题。

    Case1~5:

    这是一棵树。

    我们求出每个点i度数du[i],只走子树的期望距离g[i]和不走子树的期望距离f[i],这比较好求。

    然后累加即可。

    Case6~10:

    图中有一个环,然后环上的点都是一棵树的根。

    对于每棵树,我们同样求出每个点i度数du[i],只走子树的期望距离g[i]。

     那么怎么求不走子树的期望距离f[i]呢?

    我们先求环上的点的f[i]吧。

    我们枚举环上的点i,再枚举环上的另一个点j,求出i能到到j的距离概率和距离(有2个方向,都一样),然后f[i]+=概率*(距离+g[j])。

    现在每棵树的根节点的不走子树的期望距离f[i]已经算出来了,然后树中的点f[i]也就很容易了。

    然后累加即可。

    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<fstream>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<utility>
    #include<set>
    #include<bitset>
    #include<vector>
    #include<functional>
    #include<deque>
    #include<cctype>
    #include<climits>
    #include<complex>
    //#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj
     
    using namespace std;
    
    typedef long long LL;
    typedef double DB;
    typedef pair<int,int> PII;
    typedef complex<DB> CP;
    
    #define mmst(a,v) memset(a,v,sizeof(a))
    #define mmcy(a,b) memcpy(a,b,sizeof(a))
    #define re(i,a,b)  for(i=a;i<=b;i++)
    #define red(i,a,b) for(i=a;i>=b;i--)
    #define fi first
    #define se second
    #define m_p(a,b) make_pair(a,b)
    #define SF scanf
    #define PF printf
    #define two(k) (1<<(k))
    
    template<class T>inline T sqr(T x){return x*x;}
    template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;}
    template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;}
    
    const DB EPS=1e-9;
    inline int sgn(DB x){if(abs(x)<EPS)return 0;return(x>0)?1:-1;}
    const DB Pi=acos(-1.0);
    
    inline void clear(vector<int> *A,int a,int b){int i,j;A->clear();re(i,0,a)re(j,0,b)A[i].push_back(0);}
    
    inline int gint()
      {
            int res=0;bool neg=0;char z;
            for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
            if(z==EOF)return 0;
            if(z=='-'){neg=1;z=getchar();}
            for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
            return (neg)?-res:res; 
        }
    inline LL gll()
      {
          LL res=0;bool neg=0;char z;
            for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
            if(z==EOF)return 0;
            if(z=='-'){neg=1;z=getchar();}
            for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
            return (neg)?-res:res; 
        }
    
    const int maxN=100000;
    
    int N,M;
    int now,first[maxN+100];
    struct Tedge{int v,next,dis;}edge[2*maxN+100];
    
    DB ans;
    
    int cnt,root[maxN+100];
    int id[maxN+100];
    DB lon[maxN+100],val[maxN+100],h[maxN+100];
    
    inline void addedge(int u,int v,int dis)
      {
          now++;
          edge[now].v=v;
          edge[now].dis=dis;
          edge[now].next=first[u];
          first[u]=now;
      }
    
    int du[maxN+100],fa[maxN+100];
    DB g[maxN+100],f[maxN+100];
    
    int head,tail,que[maxN+100];
    
    inline void BFS(int S)
      {
          int i,j;
          que[head=tail=1]=S;
          fa[S]=0;
          du[S]=0;
          while(head<=tail)
            {
                int u=que[head++],v;
                for(i=first[u],v=edge[i].v;i!=-1;i=edge[i].next,v=edge[i].v)if(v!=fa[u] && id[v]==0)
                      {
                          fa[que[++tail]=v]=u;
                            du[u]++;
                            du[v]=1;
                        }
            }
          red(j,tail,1)
            {
                int u=que[j],v,dis;
                g[u]=0.0;
                for(i=first[u],v=edge[i].v,dis=edge[i].dis;i!=-1;i=edge[i].next,v=edge[i].v,dis=edge[i].dis)if(v!=fa[u] && id[v]==0)g[u]+=DB(dis)+g[v];
                int t=(u==S)?du[u]:du[u]-1;
                    if(t!=0)g[u]/=DB(t);
            }
      }
    
    inline void BFS2(int S)
      {
          int i,j;
          que[head=tail=1]=S;
          fa[S]=0;
          while(head<=tail)
            {
                int u=que[head++],v;
                for(i=first[u],v=edge[i].v;i!=-1;i=edge[i].next,v=edge[i].v)if(v!=fa[u] && id[v]==0) fa[que[++tail]=v]=u;
            }
          re(j,1,tail)
            {
                int u=que[j],v,dis;
                DB sum=0.0;
                for(i=first[u],v=edge[i].v,dis=edge[i].dis;i!=-1;i=edge[i].next,v=edge[i].v,dis=edge[i].dis)if(v!=fa[u] && id[v]==0)sum+=DB(dis)+g[v];
                if(M==N && id[u]!=0) sum+=f[u]+f[u]; else sum+=f[u];
                int t=du[u]-1;
                for(i=first[u],v=edge[i].v,dis=edge[i].dis;i!=-1;i=edge[i].next,v=edge[i].v,dis=edge[i].dis)if(v!=fa[u] && id[v]==0)
                  {
                       f[v]=sum-DB(dis)-g[v];
                      if(t!=0)f[v]/=DB(t);
                      f[v]+=DB(dis);
                  }
            }
      }
    
    int vis[maxN+100];
    int top,sta[maxN+100],last[maxN+100];
    inline void DFS()
      {
          mmst(vis,0);
          mmst(fa,0);
          vis[sta[top=1]=1]=1;
          last[1]=first[1];
          while(top>=1)
            {
                int u=sta[top],i=last[top],v;
                for(v=edge[i].v;i!=-1;i=edge[i].next,v=edge[i].v)
                  {
                    if(!vis[v])
                      {
                          vis[sta[++top]=v]=1;
                          last[top]=first[v];
                          fa[v]=u;
                          last[top-1]=edge[i].next;
                          break;
                        }
                    if(v!=fa[u] && vis[v])
                      {
                          while(sta[top]!=v)root[++cnt]=sta[top--];
                          root[++cnt]=v;
                          return;
                      }
                  }
                    if(i==-1)vis[sta[top--]]=0;
            }
      }
    
    
    int main()
      {
          freopen("park.in","r",stdin);
          freopen("park.out","w",stdout);
          int i,j;
          N=gint();M=gint();
          mmst(first,-1);now=-1;
          re(i,1,M)
            {
                int x=gint(),y=gint(),dis=gint();
                addedge(x,y,dis);
                addedge(y,x,dis);
            }
          if(M==N-1)
            {
                BFS(1);
                mmst(fa,0);
                    f[1]=0.0;BFS2(1);
                ans=0.0;
                re(i,1,N)
                  {
                      int t=(i==1)?du[i]:du[i]-1;
                      ans+=g[i]*(DB(t)/DB(du[i]))+f[i]*(1.0-DB(t)/DB(du[i]));
                  }
              ans/=DB(N);
                PF("%0.5lf
    ",ans);
                return 0;
            }
          else
            {
                DFS();
                re(i,1,cnt)id[root[i]]=i;
                re(i,1,cnt)BFS(root[i]);
                #define next(i) (i%cnt+1)
                #define qian(i) (((i-2)%cnt+cnt)%cnt+1)
                re(j,1,cnt)
                  {
                      int i,v,dis;
                      for(i=first[root[j]],v=edge[i].v,dis=edge[i].dis;i!=-1;i=edge[i].next,v=edge[i].v,dis=edge[i].dis)if(v==root[next(j)]){lon[j]=DB(dis);break;}
                  }
                re(i,1,cnt)
                  {
                      h[i]=0.0;
                      int p=i;
                      DB gailv=1e10,t=0.0;
                      while(1)
                        {
                            if(p==i) gailv/=2.0; else gailv/=DB(du[root[p]]+1);
                            t+=lon[p];
                            p=next(p);
                                    if(next(p)!=i)
                                      h[i]+=gailv*(DB(du[root[p]])/DB(du[root[p]]+1))*(t+g[root[p]]);
                                    else
                                      {
                                          h[i]+=gailv*(t+g[root[p]]);
                                          break;
                                      }
                        }
                      p=i;
                            gailv=1e10;
                            t=0.0;
                      while(1)
                        {
                            if(p==i) gailv/=2.0; else gailv/=DB(du[root[p]]+1);
                            t+=lon[qian(p)];
                            p=qian(p);
                            if(qian(p)!=i)
                                h[i]+=gailv*(DB(du[root[p]])/DB(du[root[p]]+1))*(t+g[root[p]]);
                            else
                              {
                                  h[i]+=gailv*(t+g[root[p]]);
                                  break;
                              }
                        }
                      h[i]/=1e10;
                  }
                mmst(fa,0);
                re(i,1,cnt)du[root[i]]+=2,f[root[i]]=h[i],BFS2(root[i]);
                ans=0.0;
                re(i,1,N)
                  {
                      int t=(id[i]!=0)?du[i]-2:du[i]-1;
                      ans+=g[i]*(DB(t)/DB(du[i]))+f[i]*(1.0-DB(t)/DB(du[i]));
                  }
              ans/=DB(N);
              PF("%0.5lf
    ",ans);
                return 0;
              }
          return 0;
      }
          
                      
          
    View Code
  • 相关阅读:
    一点点
    第四章:检查产品说明书
    这是一个动画效果,一个圆在桌面上动
    border-image的拉伸和平铺
    用js实现左右阴影的切换
    伪样式:hover ,:active,:focus
    画一个DIV并给它的四个角变成圆形,且加上阴影
    【转】asp.net 项目在 IE 11 下出现 “__doPostBack”未定义 的解决办法
    Full postback triggered by LinkButton inside GridView inside UpdatePanel
    苹果IOS开发者账号的区别,企业账号,个人账号,公司团队账号,教育账号
  • 原文地址:https://www.cnblogs.com/maijing/p/4693175.html
Copyright © 2011-2022 走看看