zoukankan      html  css  js  c++  java
  • HDU-4219-Randomization?

    题目描述

    给定一棵(n)个节点的树,每条边的权值为([0,L])之间的随机整数,求这棵树两点之间最长距离不超过(S)的概率。

    Input

    第一行三个整数(n,L,S)

    接下来n-1行,每行两个整数,表示树上的一条边。

    1. (1 <= T <= 512)
    2. (1 <= N <= 64)
    3. (1 <= L <= 8, 1 <= S <= 512)

    加强版:

    1. (T=1)
    2. (1 <= N <= 100)
    3. (1 <= L <= 10, 1 <= S <= 2000)

    Output

    输出树上任意两点距离都不超过(S)的概率,误差在(10^{-6})以内都在算正确

    Sample Input

    3
    2 3 2
    1 2
    4 3 4
    1 2
    2 3
    3 4
    7 4 10
    1 2
    2 3
    4 5
    2 6
    4 7
    4 6
    

    Sample Output

    Case 1: 0.750000
    Case 2: 0.500000
    Case 3: 0.624832
    

    让我们先来考虑一下未加强的数据该怎么去写?

    题目中树上两点最大距离就是树的直径。

    因此,对于一个节点,我们需要维护信息是该节点到其子树的最大值的距离的概率。

    同时,我们还要把儿子向父亲转移,即维护儿子到另一个儿子的距离的概率。

    那么,我们就可以直接树形(DP)了。

    (dp[i][j])表示节点(i)到其子树的最大值为(j)的概率。

    (Dis[i])表示当前节点的子树到父亲的距离为(i)的概率。

    (temp[i])进行储存(dp)值,因为一个(dp)值会被多次利用。

    总时间复杂度:(O(n*S*(S+L)))

    对于这个算法是无法过加强版的。

    我们可以发现,这个(dp)的时间复杂度主要累积到(temp)值的累积上。

    并且(temp)值的累积一定是连续的一段区间。

    于是我们就可以利用前缀和优化,最后再把重复的给减掉。

    时间复杂度:(O(n*S*L))

    代码如下

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define int long long
    #define u64 unsigned long long
    #define reg register
    #define Raed Read
    #define debug(x) cerr<<#x<<" = "<<x<<endl;
    #define rep(a,b,c) for(reg int a=(b),a##_end_=(c); a<=a##_end_; ++a)
    #define ret(a,b,c) for(reg int a=(b),a##_end_=(c); a<a##_end_; ++a)
    #define drep(a,b,c) for(reg int a=(b),a##_end_=(c); a>=a##_end_; --a)
    #define erep(i,G,x) for(reg int i=(G).Head[x]; i; i=(G).Nxt[i])
    
    inline int Read() {
    	int res = 0, f = 1;
    	char c;
    	while (c = getchar(), c < 48 || c > 57)if (c == '-')f = 0;
    	do res = (res << 3) + (res << 1) + (c ^ 48);
    	while (c = getchar(), c >= 48 && c <= 57);
    	return f ? res : -res;
    }
    
    template<class T>inline bool Min(T &a, T const&b) {
    	return a > b ? a = b, 1 : 0;
    }
    template<class T>inline bool Max(T &a, T const&b) {
    	return a < b ? a = b, 1 : 0;
    }
    
    const int N = 2e3+5, M = 1005, mod = 1e9 + 7;
    
    bool MOP1;
    
    int n,l,s,Case;
    
    struct Link_list {
    	int Tot,Head[N],Nxt[M<<1],to[M<<1],cost[M<<1];
    	inline void Init(void) {
    		Tot=0;
    		memset(Head,0,sizeof Head);
    	}
    	inline void AddEdgepair(int a,int b) {
    		to[++Tot]=b,Nxt[Tot]=Head[a],Head[a]=Tot;
    		to[++Tot]=a,Nxt[Tot]=Head[b],Head[b]=Tot;
    	}
    } G;
    
    struct T290 {
    	double Dis[N],dp[N][N],temp[N];
    	void dfs(int x,int pre) {
    		rep(i,1,s)dp[x][i]=0;
    		dp[x][0]=1;
    		rep(j,0,s)Dis[j]=temp[j]=0;
    		erep(i,G,x) {
    			int y=G.to[i];
    			if(y==pre)continue;
    			dfs(y,x);
    			rep(j,0,s)Dis[j]=temp[j]=0;
    			rep(j,0,l)rep(k,0,s)if(j+k<=s)Dis[j+k]+=dp[y][k]*1.0/(l+1);
    			else break;
    			rep(j,0,s)rep(k,0,s-j)temp[max((int)k,(int)j)]+=dp[x][k]*Dis[j];
    			rep(j,0,s)dp[x][j]=temp[j];
    		}
    	}
    	inline void solve(void) {
    		ret(i,1,n) {
    			int a=Raed(),b=Read();
    			G.AddEdgepair(a,b);
    		}
    		dfs(1,0);
    		double Ans=0;
    		rep(i,0,s)Ans+=dp[1][i];
    		printf("Case %lld: %.6lf
    ",++Case,Ans);
    	}
    } Pbl;
    
    struct T2100 {
    	double Dis[N],dp[N][N],temp[N],Sum1[N],Sum2[N];
    	void dfs(int x,int pre) {
    		rep(i,1,s)dp[x][i]=0;
    		dp[x][0]=1;
    		erep(i,G,x) {
    			int y=G.to[i];
    			if(y==pre)continue;
    			dfs(y,x);
    			rep(j,0,s)Dis[j]=temp[j]=0;
    			rep(j,0,l)rep(k,0,s)if(j+k<=s)Dis[j+k]+=dp[y][k]*1.0/(l+1);
    			else break;
    			Sum1[0]=dp[x][0];
    			Sum2[0]=Dis[0];
    			rep(i,1,s) {
    				Sum1[i]=Sum1[i-1]+dp[x][i];
    				Sum2[i]=Sum2[i-1]+Dis[i];
    			}
    			rep(j,0,s) {
    				int k=min(j,s-j);
    				temp[j]+=Sum1[k]*Dis[j];
    			}
    			rep(j,0,s) {
    				int k=min(j,s-j);
    				temp[j]+=Sum2[k]*dp[x][j];
    			}
    			rep(j,0,s)if(j*2<=s)temp[j]-=dp[x][j]*Dis[j];
    			rep(j,0,s)dp[x][j]=temp[j];
    		}
    	}
    	inline void solve(void) {
    		ret(i,1,n) {
    			int a=Raed(),b=Read();
    			G.AddEdgepair(a,b);
    		}
    		dfs(1,0);
    		double Ans=0;
    		rep(i,0,s)Ans+=dp[1][i];
    		printf("Case %lld: %.6lf
    ",++Case,Ans);
    	}
    } P100;
    
    bool MOP2;
    
    inline void _main(void) {
    	int T=Read();
    	while(T--) {
    		G.Init();
    		n=Raed(),l=Read(),s=Read();
    		P100.solve();
    	}
    }
    
    signed main() {
    #define offline1
    #ifdef offline
    	freopen("random.in", "r", stdin);
    	freopen("random.out", "w", stdout);
    	_main();
    	fclose(stdin);
    	fclose(stdout);
    #else
    	_main();
    #endif
    	return 0;
    }
    
  • 相关阅读:
    (29)zabbix执行远程命令
    (28)zabbix用户宏变量详解macro
    CentOS7安装Nginx及配置
    Open-Falcon 监控系统监控 MySQL/Redis/MongoDB 状态监控
    Centos7安装ansible
    Centos7部署open-falcon 0.2
    Centos7安装redis
    vim常用命令
    CentOS7安装配置Bacula yum方法
    CentOS7时间同步
  • 原文地址:https://www.cnblogs.com/dsjkafdsaf/p/11286743.html
Copyright © 2011-2022 走看看