题解 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 ...
随机推荐
- 02.Hamcrest和TestSuite介绍
1.首先第一步需要导入对应的jar包 我们来看下面的一个例子 OK,在前面的一系列博客里面,我整理过了Assert类下面常用的断言方法,比如assertEquals等等,但是org.junit.Ass ...
- 01-最大子列和问题(java)
问题描述:给定N个整数的序列{A1,A2,A3,…,An},求解子列和中最大的值. 这里我们给出{-2,11,-4,13,-5,-2}这样一个序列,正确的最大子列和为20 该题是在数据结构与算法中经常 ...
- Git【入门】这一篇就够了
前言 欢迎关注公众号,白嫖原创PDF,也可以催更,微信搜:JavaPub,回复:[666] Git 在生产工作中是使用频率很高的工具,但我发现很多文章只是对它做了简单的提交命令说明,真正遇到 版本冲突 ...
- 断路器Hystrix(Ribbon)
微服务架构中,根据业务划分成若干个服务,各单元应用间通过服务注册与订阅的方式互相依赖,依赖通过远程调用的方式执行,该方式难以避免因网络或自身原因而出现故障或者延迟,从而并不能保证服务的100%可用,此 ...
- node 模块正确暴露方法
一个node模块,为了能够服用,就需要将其暴露,那么如何正确写呢?(参考:https://developer.mozilla.org/zh-CN/docs/Learn/Server-side/Expr ...
- HDU 4352 XHXJ's LIS HDU 题解
题目 #define xhxj (Xin Hang senior sister(学姐)) If you do not know xhxj, then carefully reading the ent ...
- Git篇---将秘钥添加到github
第1步:创建SSH Key.在用户主目录下,看看有没有-/.ssh目录,如果有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果已经有了,可直接跳到下一步.如果没有,打开She ...
- 宁波市第三届网络安全大赛-WriteUp(Misc)
友情链接 Web师傅:skyxmao师傅 内心OS 第一次参加这种大型比赛,实力较菜,请师傅们多多指点 Misc | 完成 | 第一 下载文件,看一下doc没有任何问题, 没有发现任何隐写,然后修改文 ...
- Vue---day05
目录 2. 客户端项目搭建 2.1 创建项目目录 2.2 初始化项目 2.3 安装路由vue-router 2.3.1 下载安装路由组件 2.3.2 配置路由 2.3.2.1 初始化路由对象 2.3. ...
- django 本地项目部署uwsgi 以及云服务器部署 uwsgi+Nginx+Docker+MySQL主从
一 .django 本地项目部署uwsgi 1 本地部署项目 uwsgi安装测试 通过uwsgi 进行简单部署 安装uwsgi命令:pip install uwsgi -i http://pypi.d ...