题目pdf:http://acm.bnu.edu.cn/v3/external/124/12487.pdf

大致题意:

一棵树,一个人从A节点出发,等可能的选不论什么一条边走,有两个节点B,C求这个人先到达B的概率

思路:

先说结论:仅仅和离A的距离有关。先到达B+先到达A的概率 = 1,然后依据距离分配一下就好。

构造性证明:假设B-A-C在一条链上显然就是按距离分配概率。由于链上的支路对概率一点影响没有,由于假如走到支路上。你会发现,原本仅仅是向前向后各1/2的概率如今不变成1/3了吗,并非,一条链上的点往C或往B走的概率事实上永远都是1/2,由于走到支路以后还要考虑这部分最后对概率的贡献,所以它必定会回到原链上。这部分可能性任然会各一半的分流到B或C或其它支路方向,终于等于没有支路,所以假设B-A-C在一条链上显然就是按距离分配概率

若不在一条链上,以A为根,A点始终要到达LCA(B,C) ,如今又变成了一条链了,结论仍成立。

标解是,dp[x]是从x点出发先到达B的概率。显然有dp[B] = 1,dp[C] = 0.

dp[u] = sum(dp[v])/cnt(相邻的节点数),能够列线性方程,然后高斯消元解得dp[A]

这样效率就大大减少了

//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <cstring>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <string>
#include <vector>
#include <cstdio>
#include <ctime>
#include <bitset>
#include <algorithm>
#define SZ(x) ((int)(x).size())
#define ALL(v) (v).begin(), (v).end()
#define foreach(i, v) for (__typeof((v).begin()) i = (v).begin(); i != (v).end(); ++ i)
#define reveach(i, v) for (__typeof((v).rbegin()) i = (v).rbegin(); i != (v).rend(); ++ i)
#define REP(i,n) for ( int i=1; i<=int(n); i++ )
#define rep(i,n) for ( int i=0; i< int(n); i++ )
using namespace std;
typedef long long ll;
#define X first
#define Y second
typedef pair<int,int> pii;
template <class T>
inline bool RD(T &ret) {
char c; int sgn;
if (c = getchar(), c == EOF) return 0;
while (c != '-' && (c<'0' || c>'9')) c = getchar();
sgn = (c == '-') ? -1 : 1;
ret = (c == '-') ? 0 : (c - '0');
while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');
ret *= sgn;
return 1;
}
template <class T>
inline void PT(T x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9) PT(x / 10);
putchar(x % 10 + '0');
}
const int N = 233;
int n,A,B,C;
vector<int> G[N]; int dep[N];
bool vis[N];
int pa[N][20];
void BFS(int root)
{
memset(vis,0,sizeof(vis));
dep[root] = 0;
queue<int>q;
q.push(root);
pa[root][0] = root;
vis[root] = 1;
while(!q.empty())
{
int u = q.front(); q.pop();
for(int i=1;i<20;i++) pa[u][i] = pa[pa[u][i-1]][i-1];
foreach(it,G[u])
{
int v = *it;
if(vis[v] == 0)
{
vis[v] = 1;
pa[v][0] = u;
dep[v] = dep[u]+1;
q.push(v);
}
}
}
}
int LCA(int u,int v)
{
if(dep[u] > dep[v]) swap(u,v);
for(int det = dep[v]-dep[u],i = 0;det;i++,det >>= 1)
if(det&1) v=pa[v][i];
if(v == u) return v;
for(int i = 20-1;i >= 0;i--)
if(pa[u][i] != pa[v][i]) v = pa[v][i],u = pa[u][i];
return pa[u][0];
} int main(){ while(scanf("%d%d%d%d",&n,&A,&B,&C) == 4){
REP(i,n) G[i].clear();
REP(i,n-1){
int u,v;
RD(u),RD(v);
G[u].push_back(v);
G[v].push_back(u);
}
BFS(A);
int lca = LCA(B,C);
int db = dep[B]-dep[lca];
int dc = dep[C]-dep[lca];
double ans = 0;
if( db == 0) ans = 1;
else if( dc == 0) ans = 0;
else ans = dc/(double)(db+dc);
printf("%lf\n",ans);
}
}

UVA 12487 Midnight Cowboy(LCA+大YY)(好题)的更多相关文章

  1. UVA - 12487 Midnight Cowboy(LCA+思维)

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  2. UVA.11384 Help is needed for Dexter (思维题)

    UVA.11384 Help is needed for Dexter (思维题) 题意分析 同样水题一道,这回思路对了. 给出数字n,面对一个1,2,3,4--n的数字序列,你可以对他们的部分或者全 ...

  3. URAL 1614. National Project “Trams” (图论大YY)

    1614. National Project "Trams" Time limit: 0.5 second Memory limit: 64 MB President has de ...

  4. UVA 11354 Bond 最小生成树 + lca

    题意 给出一张图,q个询问,每次询问给出uv,找出一条路径,使这条路径上的最大边权是两点所有路径中最小,输出这个值 思路 很显然要先求出最小生成树,任意两点在最小生成树上有唯一路径,并且这条路径上的最 ...

  5. UVA 11582 Colossal Fibonacci Numbers! 大斐波那契数

    大致题意:输入两个非负整数a,b和正整数n.计算f(a^b)%n.其中f[0]=f[1]=1, f[i+2]=f[i+1]+f[i]. 即计算大斐波那契数再取模. 一开始看到大斐波那契数,就想到了矩阵 ...

  6. UVA 1596 Bug Hunt (大模拟 栈)

    题意: 输入并模拟执行一段程序,输出第一个bug所在的行. 每行程序有两种可能: 数组定义: 格式为arr[size]. 例如a[10]或者b[5],可用下标分别是0-9和0-4.定义之后所有元素均为 ...

  7. UVA 11389 The Bus Driver Problem 贪心水题

    题目链接:UVA - 11389 题意描述:有n个司机,n个早班路线和n个晚班路线,给每个司机安排一个早班路线和一个晚班路线,使得每个早班路线和晚班路线只属于一个司机.如果一个司机早班和晚班总的驾驶时 ...

  8. 【BZOJ-3712】Fiolki LCA + 倍增 (idea题)

    3712: [PA2014]Fiolki Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 303  Solved: 67[Submit][Status] ...

  9. UVA 558 判定负环,spfa模板题

    1.UVA 558 Wormholes 2.总结:第一个spfa,好气的是用next[]数组判定Compilation error,改成nexte[]就过了..难道next还是特殊词吗 题意:科学家, ...

随机推荐

  1. Oracle win32_11gR2_client.zip

    先将下载下来的ZIP文件解压,并运行setup.exe文件. 第一步:选择管理员(0MB)(A),然后点击下一步 第二步:选择语言,点击下一步 第三步:选择安装的路径,然后点击下一步 第四步:执行到第 ...

  2. 1004 Counting Leaves (30)(30 point(s))

    problem A family hierarchy is usually presented by a pedigree tree. Your job is to count those famil ...

  3. 机器学习之路:python 特征降维 特征筛选 feature_selection

    特征提取: 特征降维的手段 抛弃对结果没有联系的特征 抛弃对结果联系较少的特征 以这种方式,降低维度 数据集的特征过多,有些对结果没有任何关系,这个时候,将没有关系的特征删除,反而能获得更好的预测结果 ...

  4. 联系表单 1_copy

    你的名字 (必填) [text* your-name] 你的邮箱 (必填) [email* your-email] 主题 [text your-subject] 你的留言 [textarea your ...

  5. 直接插入排序(高级版)之C++实现

    直接插入排序(高级版)之C++实现 一.源代码:InsertSortHigh.cpp /*直接插入排序思想: 假设待排序的记录存放在数组R[1..n]中.初始时,R[1]自成1个有序区,无序区为R[2 ...

  6. CodeForces600E Lomsat gelral 线段树合并

    从树上启发式合并搜出来的题 然而看着好像线段树合并就能解决??? 那么就用线段树合并解决吧 维护\(max, sum\)表示值域区间中的一个数出现次数的最大值以及所有众数的和即可 复杂度\(O(n \ ...

  7. hash课堂测试补分博客

    题目要求: 开放地址法: 概念: 所谓的开放定址法就是一旦发生了冲突,就去寻找下一个空的散列地址,只要散列表足够大,空的散列地址总能找到,并将记录存入. 它的公式为: 解题过程(在下图中): 拉链法: ...

  8. Loj10166 数字游戏2

    题目描述 由于科协里最近真的很流行数字游戏,某人又命名了一种取模数,这种数字必须满足各位数字之和 modN 为 000.现在大家又要玩游戏了,指定一个整数闭区间 [a,b][a,b][a,b],问这个 ...

  9. HTML5 UI 控件Mobiscroll的使用(年月日三级联动)

    概述: 遇到制作一个html5界面,需要选择年月日,其实这个功能很常用.一般我们都是网上找,之前也没有收藏一个自己常用的,今天发现一个不错的库.特此记录一下使用过程,以便以后遇到了方面查阅. 1.官方 ...

  10. phalcon Model 'partitions' could not be loaded(模型不支持分区语句)

    注意: 很明确提示用phalcon自带的模型层是不能用partition这个关键字的 解决方法: 自己写个PDO类 然后用pdo中的query方法执行语句成功: mysql分区目的 是减少数据库的负担 ...