题目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. 洛谷 P4884 多少个1?

    题面在这里 好久没做题了2333,竟然还一次A了,神奇 大概就是等比数列然后把分母乘过去,然后直接BSGS就行了,就是要写快速乘恩... #include<bits/stdc++.h> # ...

  2. kali下利用weeman进行网页钓鱼

    工具下载链接:https://files.cnblogs.com/files/wh4am1/weeman-master.zip 利用wget命令下载zip压缩包 利用unzip命令解压 接着直接cd进 ...

  3. poj 3463 最短路+次短路

    独立写查错不能,就是维护一个次短路的dist 题意:给定一个有向图,问从起点到终点,最短路+比最短路距离长1的路的个数. Sample Input25 81 2 31 3 21 4 52 3 12 5 ...

  4. python开发_tkinter_窗口控件_自己制作的Python IDEL_博主推荐

    在了解python中的tkinter模块的时候,你需要了解一些tkinter的相关知识 下面是python的API文档中的一个简单例子: import tkinter as tk class Appl ...

  5. Codeforces Round #260 (Div. 2) B. Fedya and Maths

    B. Fedya and Maths time limit per test 1 second memory limit per test 256 megabytes input standard i ...

  6. JVM垃圾回收(GC)流程

    /* 首先介绍一下JVM中堆内存的组成: JVM堆内存主要由三部分组成: (1)新生代: 伊甸园区,存活区,伸缩区 (2)老年代: 老年区,伸缩区 (3)元空间(永久代): 元空间,伸缩区 注意:JD ...

  7. Oracle | 给表和字段添加注释

    comment  on  column  表名.字段名   is  '注释内容'; comment on column OPERATOR_INFO.MAIN_OPER_ID is '归属操作员'; c ...

  8. java基础学习总结——对象转型

    一.对象转型介绍 对象转型分为两种:一种叫向上转型(父类对象的引用或者叫基类对象的引用指向子类对象,这就是向上转型),另一种叫向下转型.转型的意思是:如把float类型转成int类型,把double类 ...

  9. restful api安全验证问题

    没有绝对的安全,这个话题很深, 下文都是自己的一些理解,水平有限,如有勘误,希望大家予以指正. 由于 RESTful Api 是基于 Http 协议的 Api,是无状态传输,所以 只要和用户身份有关的 ...

  10. LR杂记-nmon+analyser监控linux系统资源

    1.查看linux具体版本号信息 file /sbin/init 2.下载相应nmon版本号 http://pkgs.repoforge.org/nmon/ 3.安装 rpm -ivh nmon-14 ...