HDU 4443 带环树形dp
思路:如果只有一棵树这个问题很好解决,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的更多相关文章
- HDU 4514 - 湫湫系列故事——设计风景线 - [并查集判无向图环][树形DP求树的直径]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4514 Time Limit: 6000/3000 MS (Java/Others) Memory Li ...
- hdu 5452 Minimum Cut 树形dp
Minimum Cut Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=54 ...
- HDU 1520 Anniversary party [树形DP]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1520 题目大意:给出n个带权点,他们的关系可以构成一棵树,问从中选出若干个不相邻的点可能得到的最大值为 ...
- HDU 1011 Starship Troopers 树形DP 有坑点
本来是一道很水的树形DP题 设dp[i][j]表示,带着j个人去攻打以节点i为根的子树的最大收益 结果wa了一整晚 原因: 坑点1: 即使这个节点里面没有守卫,你如果想获得这个节点的收益,你还是必须派 ...
- POJ 2342 &&HDU 1520 Anniversary party 树形DP 水题
一个公司的职员是分级制度的,所有员工刚好是一个树形结构,现在公司要举办一个聚会,邀请部分职员来参加. 要求: 1.为了聚会有趣,若邀请了一个职员,则该职员的直接上级(即父节点)和直接下级(即儿子节点) ...
- hdu 1520Anniversary party(简单树形dp)
Anniversary party Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
- Install Air Conditioning HDU - 4756(最小生成树+树形dp)
Install Air Conditioning HDU - 4756 题意是要让n-1间宿舍和发电站相连 也就是连通嘛 最小生成树板子一套 但是还有个限制条件 就是其中有两个宿舍是不能连着的 要求所 ...
- HDU 3586 二分答案+树形DP判定
HDU 3586 『Link』HDU 3586 『Type』二分答案+树形DP判定 ✡Problem: 给定n个敌方据点,1为司令部,其他点各有一条边相连构成一棵树,每条边都有一个权值cost表示破坏 ...
- HDU 3586.Information Disturbing 树形dp 叶子和根不联通的最小代价
Information Disturbing Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/ ...
随机推荐
- [洛谷P4491] [HAOI2018]染色
洛谷题目链接:[HAOI2018]染色 题目背景 HAOI2018 Round2 第二题 题目描述 为了报答小 C 的苹果, 小 G 打算送给热爱美术的小 C 一块画布, 这块画布可 以抽象为一个长度 ...
- iScroll使用方法
最基本的iScroll使用结构 <div id="wrapper"> <ul> <li></li> ..... </ul> ...
- linux scp上传文件到其他机器上
scp是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的.可能会稍微影响一下速度.当你服务器 ...
- hive笔记之row_number、rank、dense_rank
hive中有三个与分组排序相关的分析函数(我起初也认为是窗口函数,后来看到手册里是把他们划到了Analytics functions下),row_number.rank.dense_rank,我一直傻 ...
- Oracle DataTable的数据批量写入数据库
insert语句,sqldataadapter.update(dataset,tablename);sqlbulkcopy.WriteToServer(datatable);三个方法的性能进行比较: ...
- 富文本存储型XSS的模糊测试之道
富文本存储型XSS的模糊测试之道 凭借黑吧安全网漏洞报告平台的公开案例数据,我们足以管中窥豹,跨站脚本漏洞(Cross-site Script)仍是不少企业在业务安全风险排查和修复过程中需要对抗的“大 ...
- CCN与CDN区别
CCN与CDN区别 相同点: 1.针对目前互联网上存在问题,提出解决方案,让数据传输更快更稳定. 2.都均衡网络流量. 区别: 1.CDN是内容分发网络,是基于目前的TCP/IP体系结构的补充方法.C ...
- mysql取字段名注意事项!!!!千万不能和关键字同名
今天就碰到一个恶心的问题,更新时update sql语句报错,查了半天感觉没问题啊,后来一行一行定位,终于找到原因了, 原来是有个字段是show,和mysql关键字冲突了,坑爹! 改了个名字就好了,或 ...
- javade多任务处理之Executors框架(线程池)实现的内置几种方式与两种基本自定义方式
一 Executors框架(线程池) 主要是解决开发人员进行线程的有效控制,原理可以看jdk源码,主要是由java.uitl.concurrent.ThreadPoolExecutor类实现的,这里只 ...
- Angular CLI 命令行工具
工欲善其事必先利其器.好的工具让开发更加简单便捷. 1.全局安装angular cli npm install -g @angular/cli 2.安装完成后就可以使用angular-cli命令行工具 ...