思路:如果只有一棵树这个问题很好解决,dp一次,然后再dfs一次往下压求答案就好啦,带环的话,考虑到环上的点不是

很多,可以暴力处理出环上的信息,然后最后一次dfs往下压求答案就好啦。细节比较多。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PII pair<int, int>
#define PLI pair<LL, int>
#define ull unsigned long long
using namespace std; const int N = 1e5 + ;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + ;
const double eps = 1e-; double ans[N], dp[N], up[N], down[N];
int n, m, tot, head[N], deg[N], edgecnt[N];
bool is[N], vis[N];
vector<int> cir;
struct Edge {
int from, to, nx;
} edge[N<<]; void addEdge(int u, int v) {
edge[tot].from = u;
edge[tot].to = v;
edge[tot].nx = head[u];
head[u] = tot++;
}
void dfs(int u) {
vis[u] = true;
cir.push_back(u);
for(int i = head[u]; ~i; i = edge[i].nx) {
int v = edge[i].to;
if(is[v] || vis[v]) continue;
dfs(v);
}
} void dfs1(int u, int fa) {
edgecnt[u] = ;
for(int i = head[u]; ~i; i = edge[i].nx) {
if(edge[i].to == fa || !is[edge[i].to]) continue;
int v = edge[i].to;
edgecnt[u]++;
dfs1(v, u);
}
dp[u] = 1.0 / (edgecnt[u]+);
if(edgecnt[u]) {
for(int i = head[u]; ~i; i = edge[i].nx) {
if(edge[i].to == fa || !is[edge[i].to]) continue;
int v = edge[i].to;
dp[u] += dp[v] / edgecnt[u];
}
}
} void dfs2(int u, int fa, double val) {
if(!edgecnt[u]) {
ans[u] += val;
return;
}
double sum = ;
for(int i = head[u]; ~i; i = edge[i].nx) {
if(edge[i].to == fa || !is[edge[i].to]) continue;
sum += dp[edge[i].to];
}
if(!fa) {
for(int i = head[u]; ~i; i = edge[i].nx) {
if(edge[i].to == fa || !is[edge[i].to]) continue;
int v = edge[i].to;
if(edgecnt[u] == ) dfs2(v, u, 1.0/(edgecnt[u]+)+val);
else dfs2(v, u, 1.0/(edgecnt[u]+)+val/edgecnt[u]+(sum-dp[v])/(edgecnt[u]+));
}
} else {
for(int i = head[u]; ~i; i = edge[i].nx) {
if(edge[i].to == fa || !is[edge[i].to]) continue;
int v = edge[i].to;
dfs2(v, u, 1.0/(edgecnt[u]+)+val/edgecnt[u]+(sum-dp[v])/edgecnt[u]);
}
}
} void init() {
tot = ; cir.clear();
for(int i = ; i <= n; i++)
head[i]=-, ans[i]=deg[i]=is[i]=vis[i]=;
} int main() {
while(scanf("%d", &n) != EOF && n) {
init();
for(int i = ; i <= n; i++) {
int u, v; scanf("%d%d", &u, &v);
addEdge(u, v); addEdge(v, u);
deg[u]++, deg[v]++;
}
queue<int> que;
for(int i = ; i <= n; i++) {
if(deg[i] == ) {
que.push(i);
is[i] = true;
}
}
while(!que.empty()) {
int u = que.front(); que.pop();
for(int i = head[u]; ~i; i = edge[i].nx) {
int v = edge[i].to;
if(is[v]) continue;
deg[v]--, deg[u]--;
if(deg[v] == ) {
is[v] = true;
que.push(v);
}
}
} for(int i = ; i <= n; i++)
if(!is[i] && !vis[i]) dfs(i); int cnt = cir.size();
for(int i = ; i < cnt; i++) {
int root = cir[i];
dfs1(root, );
up[root] = 1.0*/(edgecnt[root]+); down[root] = ;
for(int j = head[root]; ~j; j = edge[j].nx) {
int v = edge[j].to;
if(!is[v]) continue;
up[root] += dp[v]*/(edgecnt[root]+);
}
} for(int i = ; i < cnt; i++) {
double now = up[cir[i]]/;
for(int k = ; k < cnt; k++) {
int j = (i+k)%cnt;
if(k == cnt-) down[cir[j]] += now;
else down[cir[j]] += now*(edgecnt[cir[j]])/(edgecnt[cir[j]]+);
now /= edgecnt[cir[j]]+;
}
now = up[cir[i]]/;
for(int k = ; k < cnt; k++) {
int j = (i-k+cnt)%cnt;
if(k == cnt-) down[cir[j]] += now;
else down[cir[j]] += now*(edgecnt[cir[j]])/(edgecnt[cir[j]]+);
now /= edgecnt[cir[j]]+;
}
}
for(int i = ; i < cnt; i++)
dfs2(cir[i], , down[cir[i]]); sort(ans+, ans++n);
reverse(ans+, ans++n);
double ret = ;
for(int i = ; i <= ; i++)
ret += ans[i];
printf("%.5f\n", ret/n);
}
return ;
} /*
*/

HDU 4443 带环树形dp的更多相关文章

  1. HDU 4514 - 湫湫系列故事——设计风景线 - [并查集判无向图环][树形DP求树的直径]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4514 Time Limit: 6000/3000 MS (Java/Others) Memory Li ...

  2. hdu 5452 Minimum Cut 树形dp

    Minimum Cut Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=54 ...

  3. HDU 1520 Anniversary party [树形DP]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1520 题目大意:给出n个带权点,他们的关系可以构成一棵树,问从中选出若干个不相邻的点可能得到的最大值为 ...

  4. HDU 1011 Starship Troopers 树形DP 有坑点

    本来是一道很水的树形DP题 设dp[i][j]表示,带着j个人去攻打以节点i为根的子树的最大收益 结果wa了一整晚 原因: 坑点1: 即使这个节点里面没有守卫,你如果想获得这个节点的收益,你还是必须派 ...

  5. POJ 2342 &&HDU 1520 Anniversary party 树形DP 水题

    一个公司的职员是分级制度的,所有员工刚好是一个树形结构,现在公司要举办一个聚会,邀请部分职员来参加. 要求: 1.为了聚会有趣,若邀请了一个职员,则该职员的直接上级(即父节点)和直接下级(即儿子节点) ...

  6. hdu 1520Anniversary party(简单树形dp)

    Anniversary party Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

  7. Install Air Conditioning HDU - 4756(最小生成树+树形dp)

    Install Air Conditioning HDU - 4756 题意是要让n-1间宿舍和发电站相连 也就是连通嘛 最小生成树板子一套 但是还有个限制条件 就是其中有两个宿舍是不能连着的 要求所 ...

  8. HDU 3586 二分答案+树形DP判定

    HDU 3586 『Link』HDU 3586 『Type』二分答案+树形DP判定 ✡Problem: 给定n个敌方据点,1为司令部,其他点各有一条边相连构成一棵树,每条边都有一个权值cost表示破坏 ...

  9. HDU 3586.Information Disturbing 树形dp 叶子和根不联通的最小代价

    Information Disturbing Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/ ...

随机推荐

  1. Git和Github入门

    推文:官方手册,十分详细 推文:git和github快速入门 一.git使用 1.git安装 (1)windows 网站:https://git-scm.com/download/win下载安装即可 ...

  2. (一)在Lingo中使用集合

    1.    在Lingo中使用集合 4.1 集合的基本用法和lingo模型的基本要素 Lingo虽然使用方便,但是如果要解决几万个,几十万个变量的优化问题时,我们总不能一个一个地列出x1,x2,…,x ...

  3. bzoj 2111 [ZJOI2010]Perm 排列计数(DP+lucas定理)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2111 [题意] 给定n,问1..n的排列中有多少个可以构成小根堆. [思路] 设f[i ...

  4. zabbix lld使用trapper方式(zabbix_sender)

    自动发现脚本文件输出格式: { "data": [ { "{#BIND_PERF}": "BIND INCOMING QUERY" }, { ...

  5. nginx配置php时fastcgi_pass参数问题

    更多内容推荐微信公众号,欢迎关注: 在配置nginx的时候,fastcgi_pass的配置问题,如下所示: location ~ \.php$ { root /home/wwwroot; fastcg ...

  6. Css3帧动画深入探寻,讲点项目中实际会碰到的问题

    先加个副标题XD --如何解决background-size为100%下处理@keyframes 正是在项目中遇到副标题,才引起我更深入的探寻 先略带一下基本的css3动画 css3的动画实现是通过属 ...

  7. C. Connect Three(构造)

    题目链接:http://codeforces.com/contest/1087/problem/C 题目大意:给你三个点的坐标,让你用尽可能少的方块,让这三个点连起来. 具体思路: 我们先对这三个点进 ...

  8. J - Clairewd’s message HDU - 4300(扩展kmp)

    题目链接:https://cn.vjudge.net/contest/276379#problem/J 感觉讲的很好的一篇博客:https://subetter.com/articles/extend ...

  9. Ubuntu 12.04 更新源的方法及地址

    本文章转自:http://www.maybe520.net/blog/424/ 安装好ubuntu 12.04之后,可以联网之后,马上要做的最重要的事情之一就是配置更新源列表,这样以后安装更新或者软件 ...

  10. GRUB (简体中文)

    原文链接:https://wiki.archlinux.org/index.php/GRUB_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87) 前言 引导程序是计算机启动时 ...