原题链接

题意实际上就是让你添加尽量少的边,使得每个点都在至少一个环上。

显然对于在一个边双连通分量里的点已经满足要求,所以可以用\(tarjan\)找边双并缩点。

对于缩点后的树,先讲下我自己的弱鸡做法,每次找直径,因为将直径改为环显然使得新添的边贡献最大,这样贪心的连下去,直到所有点满足要求为止。

而实际上有一个简单结论,该题答案就是缩点后树的叶子节点个数除\(2\)(向上取整)。

代码是用的我自己的弱鸡做法。

#include<cstdio>
using namespace std;
const int N = 5010;
const int M = 2e4 + 10;
int fi[N], di[M], ne[M], cfi[N], cdi[M], cne[M], dfn[N], low[N], bl[N], pre[N], l = 1, lc, ti, DCC, ma, ma_id;
bool bg[M], v[N];
inline int re()
{
int x = 0;
char c = getchar();
bool p = 0;
for (; c < '0' || c > '9'; c = getchar())
p |= c == '-';
for (; c >= '0' && c <= '9'; c = getchar())
x = x * 10 + c - '0';
return p ? -x : x;
}
inline void add(int x, int y)
{
di[++l] = y;
ne[l] = fi[x];
fi[x] = l;
}
inline void add_c(int x, int y)
{
cdi[++lc] = y;
cne[lc] = cfi[x];
cfi[x] = lc;
}
inline int minn(int x, int y)
{
return x < y ? x : y;
}
void tarjan(int x, int la)
{
int i, y;
dfn[x] = low[x] = ++ti;
for (i = fi[x]; i; i = ne[i])
if (!dfn[y = di[i]])
{
tarjan(y, i);
low[x] = minn(low[x], low[y]);
if (low[y] > dfn[x])
bg[i] = bg[i ^ 1] = 1;
}
else
if (i ^ la ^ 1)
low[x] = minn(low[x], dfn[y]);
}
void dfs(int x)
{
int i, y;
bl[x] = DCC;
for (i = fi[x]; i; i = ne[i])
if (!bl[y = di[i]] && !bg[i])
dfs(y);
}
void dfs_2(int x, int fa, int d)
{
int i, y;
if (ma < d)
{
ma = d;
ma_id = x;
}
pre[x] = fa;
for (i = cfi[x]; i; i = cne[i])
if ((y = cdi[i]) ^ fa)
dfs_2(y, x, v[x] && v[y] ? d : d + 1);
}
int main()
{
int i, n, m, x, y, s = 0;
n = re();
m = re();
for (i = 1; i <= m; i++)
{
x = re();
y = re();
add(x, y);
add(y, x);
}
for (i = 1; i <= n; i++)
if (!dfn[i])
tarjan(i, 0);
for (i = 1; i <= n; i++)
if (!bl[i])
{
DCC++;
dfs(i);
}
for (i = 2; i <= l; i += 2)
{
x = bl[di[i ^ 1]];
y = bl[di[i]];
if (x ^ y)
{
add_c(x, y);
add_c(y, x);
}
}
while (DCC > 1)
{
ma = ma_id = 0;
dfs_2(1, 0, 0);
ma = 0;
dfs_2(ma_id, 0, 0);
for (i = ma_id; i; i = pre[i])
if (!v[i])
{
v[i] = 1;
DCC--;
}
s++;
}
printf("%d", DCC ^ 1 ? s : s ? s + 1 : s);
return 0;
}

最新文章

  1. UILabel 自适应宽高
  2. 浅谈WEB跨域的实现(前端向)
  3. Final阶段用户调查报告
  4. alphaBlend
  5. 软删除脏数据job笔记
  6. PHP计划任务之关闭浏览器后仍然继续执行的函数
  7. Cygwin下vim按方向键出现ABCD;
  8. 安装Redis无错流程
  9. 18 Loader 总结
  10. Postman用法简介
  11. 使用SQLsever批量查询TXT文本中的值
  12. ReactiveX 学习笔记(5)合并数据流
  13. UI设计初学者必备的工具以及学习路线(附思维导图)
  14. 腾讯云点播视频存储(Web端视频上传)
  15. Tomcat7出现HTTP Status 500 - java.lang.ClassCastException: org.apache.jasper.el.ELContextImpl cannot be cast to org.apache.jasper.el.ELContextImpl的解决
  16. map函数原理
  17. SSM框架整合的详细过程(含每一步的分析及代码)。实质上是SpringMVC与mybatis的整合,应为spring与SpringMVC不需要整合。
  18. Codeforces 19.E Fairy
  19. C# Console类的方法使用总结
  20. 2.LVS配置过程

热门文章

  1. Java KeyNote
  2. windows(cr lf )转unix (lf)
  3. 反射实现 AOP 动态代理模式(Spring AOP 的实现原理)
  4. 完整性约束&amp;外键变种三种关系&amp;数据的增删改
  5. ucore-lab1-练习2report
  6. pta7-20 畅通工程之局部最小花费问题(Kruskal算法)
  7. PHP文件上传与下载
  8. tight
  9. Angular之响应式表单 ( Reactive Forms )
  10. Framework7框架结构