UVALive-8072 Keeping On Track 树形dp 联通块之间缺失边的个数
题目链接:https://cn.vjudge.net/problem/UVALive-8072
题意
给出n+1个点和n条边,每对点之间只能存在一条边。
现在要找出一个节点,使得去掉这个点后,所剩每对不联通点的点对数最大。
还要在去掉这个点后加上一条边,使得加上这个边后,不联通点对数最小。
例:
6
0 1
1 2
2 3
2 4
4 5
4 6
答:11 5
思路
看不懂题意,更看不懂样例;只能临场猜题意,猜样例。
现在解释一下样例的意思。
首先画出这个无向图,然后找特殊节点。我帮你找到2这个节点是特殊点。
那么去掉节点2,现在有三个联通子图,分别是456-3-01。
再数缺失点对:4-3; 4-0; 4-1; 5-3;...,一共11对。
现在加上60这条边,缺失点对就是最小的5。(当然41也可以,实际上只要最大的两个联通图链接起来即可)
好的现在看懂题意了,显然发现原图是颗树。
而特殊节点就是树里边的某个节点。
去掉这个节点,可以使图分为子节点数+1个联通图。
缺失点对其实就是联通图点数分别乘当前的前缀和(当然,等于每个点数相乘,但是复杂度降低了)。
比如说样例的2节点,使原图分为3个联通图,点数为3,1,2。
那么缺失点对数计算如下:
31+(3+1)2=11
加一条边的最少缺失点对的计算,其实就是问哪两个联通图组合起来,有最少缺失点对。
很显然是最大的两个图组合起来(回忆初中二次函数问题,点数和等于n-1)。
这样我们首先树形dp算子树大小、计算缺失点对,最后查最大值,计算最小缺失点对即可。
整个复杂度可以到达O(n)。
提交过程
| WA | 少写个加号 |
| AC |
代码
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=1e4+20;
vector<int> son[maxn];
int data[maxn], n, fat[maxn];
long long val[maxn];
int dp(int u, int fa){
fat[u]=fa;
if (data[u]>0) return data[u];
vector<int> pre, tmp;
data[u]=1;
for (int i=0; i<son[u].size(); i++) if (son[u][i]!=fa){
tmp.push_back(dp(son[u][i], u));
if (tmp.size()!=1) pre.push_back(pre.back()+tmp.back());
else pre.push_back(tmp.back());
data[u]+=tmp.back();
}
int size=tmp.size();
if (size==0) val[u]=0;
else{
val[u]=pre[size-1]*(n-data[u]+1);
for (int i=1; i<size; i++)
val[u]+=pre[i-1]*tmp[i];
}
return data[u];
}
void solve(void){
long long mmax=0, idx=0;
for (int i=0; i<=n; i++) if (mmax<val[i]){
idx=i; mmax=val[i];
}
int psize=0, tmp[maxn];
for (int i=0; i<son[idx].size(); i++) if (son[idx][i]!=fat[idx])
tmp[psize++]=dp(son[idx][i], idx);
tmp[psize++]=n+1-data[idx];
sort(tmp, tmp+psize);
tmp[psize-2]+=tmp[psize-1];
psize--;
long long ans=0, pree=tmp[0];
for (int i=1; i<psize; i++){
ans+=pree*tmp[i];
pree+=tmp[i];
}
printf("%lld %lld\n", mmax, ans);
}
int main(void){
int a, b;
while (scanf("%d", &n)==1){
memset(data, -1, sizeof(data));
for (int i=0; i<=n; i++) son[i].clear();
for (int i=0; i<n; i++){
scanf("%d%d", &a, &b);
son[a].push_back(b);
son[b].push_back(a);
}
dp(0, -1);
solve();
}
return 0;
}
| Time | Memory | Length | Lang | Submitted |
|---|---|---|---|---|
| 33ms | 1650 | C++ 5.3.0 | 2018-08-23 04:16:14 |
UVALive-8072 Keeping On Track 树形dp 联通块之间缺失边的个数的更多相关文章
- 青云的机房组网方案(简单+普通+困难)(虚树+树形DP+容斥)
题目链接 1.对于简单的版本n<=500, ai<=50 直接暴力枚举两个点x,y,dfs求x与y的距离. 2.对于普通难度n<=10000,ai<=500 普通难度解法挺多 ...
- 联考day7 C. 树和森林 树形DP
题目描述 样例 样例输入 8 5 BBWWWBBW 1 2 2 3 4 5 6 7 7 8 样例输出 84 2 1 4 样例解释 分析 首先,我们要预处理出一个点到该联通块内所有点的距离之和 \(f\ ...
- bzoj2200拓扑排序+最短路+联通块
自己写的不知道哪里wa了,明明和网上的代码差不多.,. /* 给定一张图,有的边是无向边,有的是有向边,有向边不会出现在环中,且有可能是负权值 现在给定起点s,求出s到其余所有点的最短路长度 任何存在 ...
- 分别利用并查集,DFS和BFS方法求联通块的数量
联通块是指给定n个点,输入a,b(1<=a,b<=n),然后将a,b连接,凡是连接在一起的所有数就是一个联通块: 题意:第一行输入n,m,分别表示有n个数,有输入m对连接点,以下将要输入m ...
- HDU 3586.Information Disturbing 树形dp 叶子和根不联通的最小代价
Information Disturbing Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/ ...
- hdu 2242双联通分量+树形dp
/*先求出双联通缩点,然后进行树形dp*/ #include<stdio.h> #include<string.h> #include<math.h> #defin ...
- Codeforces Round #263 (Div. 2) D. Appleman and Tree(树形DP)
题目链接 D. Appleman and Tree time limit per test :2 seconds memory limit per test: 256 megabytes input ...
- HDU5739 Fantasia 树形dp + 点双缩点
这个题当时打多校的时候有思路,但是代码能力差,没有写出来 事后看zimpha巨巨的题解,看了觉得基本差不多 核心思路:就是找出割点,然后变成森林,然后树形dp就可以搞了 关键就在重新构图上,缩完点以后 ...
- bzoj 1040 [ZJOI2008]骑士(基环外向树,树形DP)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1040 [题意] 给一个基环森林,每个点有一个权值,求一个点集使得点集中的点无边相连且权 ...
随机推荐
- C语言提高 (1) 第一天 数据类型本质与内存四区
(物联网的分层的概念 b/s c/s 结构 习惯: 在C语言 0 函数执行成功 <0是错误 >1做一些返回值处理 3 课前准备 工作经验,记录 4 数据类型的本质 数据类型的本质是固定大小 ...
- UID和GID(详细说明)
一.UID(User Identify)中文用户ID,相当于身份证一样,在系统中是唯一的. 用户分类centos6超级用户 UID=0 root普通用户 UID=500起 oldboy虚拟用户 UID ...
- spring和struts整合
整合准备:导入jar包 如果只是访问action,没有做数据库方面的操作的话 只需要导入下面的jar spring相关jar 以及struts相关jar包 整合过程: 用到了struts所以需要在we ...
- 参数化取值策略Sequential
1.Sequential+Each iteration(顺序方式+每次迭代更新取值),设置Run—Logic中action循环迭代11次,并运行以上脚本,结果如下: 2.Sequential+ ...
- BA-siemens-insight-event builder使用
event builder功能主要是用来给report使用的,作为一个独立的对象,这个对象的功能就是收集点位的信息,如果再使用report功能就可以显示或输出点位的信息.
- 电脑-制作WIN7启动U盘
1.需要准备的工具:win7系统盘(安装盘,不是ghost),软碟通工具,大于4G的U盘
- 工具-VS CODE安装
在Linux下的安装 1.下载tar.gz文件包, 2.要注意加一条命令,这样在任何目录下就可以使用code .直接启动应用程序了 1 sudo ln -s /path/to/vscode/Code ...
- HDU 5167
范围 内的斐波那契的数不多,求出范围内的数,再暴力枚举即可. #include <iostream> #include <cstdio> #include <algori ...
- wifi共享精灵2014.04.25.001已经更新,wifi热点中文名走起!
五一回来后,有个惊喜,wifi共享精灵有了最新动向.不晓得wifi共享精灵是啥的朋友,我来解释下,它就相当于一个无线路由器.说起来,Wifi共享精灵正式版2014.04.25.001(http://w ...
- 在ActivityA中关闭还有一个ActivityB
1.对于简单的两个Activity public class A_activity extends Activity { public static A_activity _instance = nu ...