题解 CF51F 【Caterpillar】
根据毛毛虫的定义,我们不难发现在双连通分量中的点我们都需要进行合并操作,所以我们先进行\(tarjan\)缩边双连通分量,使原图变成一棵树,缩点对答案产生的贡献为每个双连通分量的\(size-1\)
然后我们继续考虑树的情况,发现,若要将树变成毛毛虫,最优的操作是保留叶子节点和除去叶子后的直径,于是我们记录叶子节点个数\(le\),除去叶子后的直径长度\(dist\)
但可能不止不止一棵树,缩点后可能为森林,所以最后还需将森林合并,我们再记录树的个数\(num\)
则最终答案为\(ans= \displaystyle\sum_{i=1}^{co\_cnt}(siz[i]-1)+co\_cnt-dist-le+num-1\)
其他实现的细节就看代码吧
\(code:\)
#include<bits/stdc++.h>
#define maxn 20010
#define maxm 200010
using namespace std;
template<typename T> inline void read(T &x)
{
x=0;char c=getchar();bool flag=false;
while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
if(flag)x=-x;
}
int n,m,ans,num;
struct Edge
{
int x,y;
}ed[maxm];
struct edge
{
int to,nxt;
}e[maxm];
int head[maxn],edge_cnt=1;
void add(int from,int to)
{
e[++edge_cnt]=(edge){to,head[from]};
head[from]=edge_cnt;
}
int dfn[maxn],low[maxn],dfn_cnt;
bool bri[maxn];
void tarjan(int x,int ed)
{
dfn[x]=low[x]=++dfn_cnt;
for(int i=head[x];i;i=e[i].nxt)
{
int y=e[i].to;
if(!dfn[y])
{
tarjan(y,i);
low[x]=min(low[x],low[y]);
if(dfn[x]<low[y]) bri[i]=bri[i^1]=true;
}
else if(i!=(ed^1)) low[x]=min(low[x],dfn[y]);
}
}
int co_cnt;
int co[maxn],siz[maxn];
void dfs_co(int x)
{
co[x]=co_cnt;
siz[co_cnt]++;
for(int i=head[x];i;i=e[i].nxt)
{
int y=e[i].to;
if(co[y]||bri[i]) continue;
dfs_co(y);
}
}
void clear()
{
edge_cnt=1;
memset(head,0,sizeof(head));
}
int le;
bool vis[maxn],leaf[maxn];
void dfs_le(int x)
{
vis[x]=true;
bool son=true;
for(int i=head[x];i;i=e[i].nxt)
{
int y=e[i].to;
if(vis[y]) continue;
son=false;
dfs_le(y);
}
if(son)
{
leaf[x]=true;
le++;
}
}
int nd,maxd,dist;
int dis[maxn];
void dfs_find(int x,int fa,int de)
{
vis[x]=true;
if(de>=maxd)
{
maxd=de;
nd=x;
}
for(int i=head[x];i;i=e[i].nxt)
{
int y=e[i].to,v=1;
if(y==fa||leaf[y]) continue;
dfs_find(y,x,de+v);
}
}
int main()
{
read(n),read(m);
for(int i=1;i<=m;++i)
{
int a,b;
read(a),read(b);
add(a,b),add(b,a);
ed[i]=(Edge){a,b};
}
for(int i=1;i<=n;++i)
if(!dfn[i])
tarjan(i,0);
for(int i=1;i<=n;++i)
{
if(!co[i])
{
co_cnt++;
dfs_co(i);
}
}
for(int i=1;i<=co_cnt;++i)
ans+=siz[i]-1;
clear();
for(int i=1;i<=m;++i)
{
int x=ed[i].x,y=ed[i].y;
if(co[x]==co[y]) continue;
add(co[x],co[y]),add(co[y],co[x]);
}
for(int i=1;i<=co_cnt;++i)
{
if(!vis[i])
{
dfs_le(i);
num++;
int tot=0;
for(int p=head[i];p;p=e[p].nxt) tot++;
if(tot==1)
{
leaf[i]=true;
le++;
}
}
}
memset(vis,0,sizeof(vis));
for(int i=1;i<=co_cnt;++i)
{
if(!vis[i]&&!leaf[i])
{
nd=maxd=0;
dfs_find(i,0,1);
dfs_find(nd,0,1);
dist+=maxd;
}
}
printf("%d",ans+co_cnt-dist-le+num-1);
return 0;
}
题解 CF51F 【Caterpillar】的更多相关文章
- CF51F Caterpillar (边双+树形DP)
题目传送门 题目大意:给你一张n个点m条边的图.每次操作可以把两个点合并成一个(与之相连的边也都要连到新点上).求把图中每个联通块都变成“毛毛虫”的最小操作次数.“毛毛虫”必须是一棵树(可以存在自环) ...
- Educational Codeforces Round 10 A. Gabriel and Caterpillar 模拟
A. Gabriel and Caterpillar 题目连接: http://www.codeforces.com/contest/652/problem/A Description The 9-t ...
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...
- 2016ACM青岛区域赛题解
A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- poj1399 hoj1037 Direct Visibility 题解 (宽搜)
http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...
随机推荐
- 729. My Calendar I
原题链接:https://leetcode.com/problems/my-calendar-i/description/ 我的答案 虽然自己实现出来了,但是没看懂这道题目考查的是什么?编程语言的熟练 ...
- mysqldump: Got error: 1044: Access denied for user 'root'@'%' to database 'hhh' when using LOCK TABLES
错误原因:mysqldump 命令执行时,需要四种权限,分别是:select,show view,trigger,lock table.但是因为没有lock table的权限,导致上述错误发生. 修改 ...
- python检测“无内容”图片
思路1:通过图像熵检测,“无内容”图像熵较小,可通过设置阈值检测“无内容”图像,计算图像熵可参考:https://www.cnblogs.com/niulang/p/12195152.html 思路2 ...
- EFCore-一对一配置外键小记2
前后两次遇到这样的错误: The property 'xx' on entity type 'xxxx' has a temporary value. Either set a permanent v ...
- linux crontab 定时任务 邮件问题 及其相关的 dead.letter 问题
最近开发项目的时候发现公司服务器用root账号登录的时候 一直会提示有新的信件,一直提示一直提示. 联想到另一台服务器上 的dead.letter文件每天都不断的变大 而且在 root家目录里 ,系 ...
- 四. django template模版
往前端浏览器pull一些字符串,这些字符串是一些数据, 那如果想让这些数据按我们的某种格式美化一点/增加样式/图片,就需要用到django提供的模版--模版就是为了让数据看起更美观. 加载模版 dja ...
- python中的多任务--线程
什么是多任务? 简单地说,就是操作系统可以同时运行多个任务. 实现多任务有多种方式,线程.进程.协程. 多任务的概念:并行和并发 并发:指的是任务数多余cpu核数,通过操作系统的各种任务调度算法, 实 ...
- Flutter —快速开发的IDE快捷方式
老孟导读:这是老孟翻译的精品文章,文章所有权归原作者所有. 欢迎加入老孟Flutter交流群,每周翻译2-3篇付费文章,精彩不容错过. 原文地址:https://medium.com/flutter- ...
- 阿里云Linux CentOS8.1 64位服务器安装LNMP(Linux+Nginx+MySQL+PHP) 并发调试之调试工具ab(apache bench)
ab 测试工具,全称是 apache bench ,是 Apache 提供的一款测试工具,具有简单易上手的特点,在测试 Web 服务时非常实用. ab 可以在 Windows 系统中使用,也可以在 L ...
- 猿灯塔:Java程序员月薪三万,需要技术达到什么水平?
最近跟朋友在一起聚会的时候,提了一个问题,说Java程序员如何能月薪达到二万,技术水平需要达到什么程度?人回答说这只能是大企业或者互联网企业工程师才能拿到.也许是的,小公司或者非互联网企业拿二万的不太 ...