题目传送门


题目描述

  为了从F个草场中的一个走到另一个,贝茜和她的同伴们有时不得不路过一些她们讨厌的可怕的树.奶牛们已经厌倦了被迫走某一条路,所以她们想建一些新路,使每一对草场之间都会至少有两条相互分离的路径,这样她们就有多一些选择。
  每对草场之间已经有至少一条路径.给出所有R条双向路的描述,每条路连接了两个不同的草场,请计算最少的新建道路的数量, 路径由若干道路首尾相连而成.两条路径相互分离,是指两条路径没有一条重合的道路.但是,两条分离的路径上可以有一些相同的草场. 对于同一对草场之间,可能已经有两条不同的道路,你也可以在它们之间再建一条道路,作为另一条不同的道路。


输入格式

第1行输入F和R,接下来R行,每行输入两个整数,表示两个草场,它们之间有一条道路。


输出格式

最少的需要新建的道路数。


样例

样例输入:

7 7
1 2
2 3
3 4
2 5
4 5
5 6
5 7

样例输出:

2


数据范围与提示

图中实线表示已有的道路,虚线表示新建的两条道路。

现在可以检验一些路径,比如:

草场1和草场2:1→2和1→6→5→2。

草场1和草场4:1→2→3→4和1→6→5→4。

草场3和草场7:3→4→7和3→2→5→7。

         事实上,每一对草场之间都连接了两条分离的路径。

1≤F≤5000,F-1≤R≤10000。

注意会有重边!!!


题解

看到这道题,马上想到了塔尖,缩e-DCC。

然后答案即为得到的$\frac{这棵树上的叶子节点的个数+1}{2}$,利用性质,连边为1的点即为叶子节点,统计答案即可。

代码细节较多,建议尝试自己根据自己的理解手打。

当然也有大神缩v-DCC,直接A掉。

还有这么一种解法,塔尖之后不用重新建图,而是直接判断在一条边两端的点low的值是否相同,如果不同那么就让度数+1。(他们的塔尖通过在一开始直接判断e.to是否等于father,如果相等直接continue)。

但是这样并不正确!!!

考虑这道题会有重边,所以如果low[x]≠low[y],但是它们还可能属于一个强联通分量。

不过如果你使用了可以规避重边的方法,那么就没有问题。

综上所述,板子要理解,并能灵活运用!!!


代码时刻

e-DCC

#include<bits/stdc++.h>
using namespace std;
struct rec
{
int from;
int nxt;
int to;
}e[200010],wzc[200010];
int head[5010],cnt=1;
int headw[5010],cntw=1;
int F,R;
int dfn[5010],low[5010],tot;
bool bridge[200010];
int c[5010],dcc;
int ans[5010];
int sum;
bool vis[5010];
void add(int x,int y)
{
e[++cnt].nxt=head[x];
e[cnt].from=x;
e[cnt].to=y;
head[x]=cnt;
}
void tarjan(int x,int in_edge)//判断桥
{
dfn[x]=low[x]=++tot;
for(int i=head[x];i;i=e[i].nxt)
{
if(!dfn[e[i].to])
{
tarjan(e[i].to,i);
low[x]=min(low[x],low[e[i].to]);
if(dfn[x]<low[e[i].to])
bridge[i]=bridge[i^1]=1;
}
else if(i!=(in_edge^1))
low[x]=min(low[x],dfn[e[i].to]);
}
}
void dfs(int x)//求e-DCC
{
c[x]=dcc;
for(int i=head[x];i;i=e[i].nxt)
{
if(c[e[i].to]||bridge[i])continue;
dfs(e[i].to);
}
}
int main()
{
scanf("%d%d",&F,&R);
for(int i=1;i<=R;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
for(int i=1;i<=F;i++)
if(!dfn[i])tarjan(i,0);
for(int i=1;i<=F;i++)
if(!c[i])
{
++dcc;
dfs(i);
}
for(int i=2;i<=cnt;i++)//开始计算答案
if(c[e[i].from]!=c[e[i].to])ans[c[e[i].from]]++;
for(int i=1;i<=dcc;i++)
if(ans[i]==1)sum++;
printf("%d",(sum+1)/2);
return 0;
}

v-DCC

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
int const maxn=5010;
struct node{int st,to,nxt;}l[4*maxn];
vector<int>v[maxn];
int n,m,head[maxn],tot,num,in[maxn*2],ans;
int dfn[maxn],low[maxn],stack[maxn],bl[maxn*2],id[maxn*2],cut[maxn*2],top,now,cnt,rt;
void add1(int x,int y)
{
l[++tot].to=y;
l[tot].st=x;
l[tot].nxt=head[x];
head[x]=tot;
}
void tarjan(int x)//割点
{
dfn[x]=low[x]=++now,stack[++top]=x;
if(x==rt&&head[x]==0)
{
v[++cnt].push_back(x);
bl[x]=cnt;
return ;
}
int flag=0;
for(int i=head[x];i;i=l[i].nxt)
{
int y=l[i].to;
if(!dfn[y])
{
tarjan(y);
low[x]=min(low[x],low[y]);
if(low[y]>=dfn[x])
{
flag++;
if(x!=rt||flag>1) cut[x]=1;
cnt++;int z;
do{
z=stack[top--];
v[cnt].push_back(z);
bl[z]=cnt;
}while(y!=z);
v[cnt].push_back(x);
}
}
else low[x]=min(low[x],dfn[y]);
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1,x,y;i<=m;i++)
{
scanf("%d%d",&x,&y);
add1(x,y),add1(y,x);
}
for(int i=1;i<=n;i++) if(!dfn[i]) rt=i,tarjan(i);
num=cnt;
for(int i=1;i<=n;i++) if(cut[i]) id[i]=++num;
for(int i=1;i<=cnt;i++)
for(int j=0;j<v[i].size();j++)
if(cut[v[i][j]]) in[i]++;
for(int i=1;i<=cnt;i++) if(in[i]==1) ans++;
printf("%d",(ans+1)/2);
return 0;
}

rp++

[BZOJ1718]:[Usaco2006 Jan] Redundant Paths 分离的路径(塔尖)的更多相关文章

  1. BZOJ1718 [Usaco2006 Jan] Redundant Paths 分离的路径

    给你一个无向图,问至少加几条边可以使整个图变成一个双联通分量 简单图论练习= = 先缩点,ans = (度数为1的点的个数) / 2 这不是很好想的么QAQ 然后注意位运算的优先级啊魂淡!!!你个sb ...

  2. BZOJ1718: [Usaco2006 Jan] Redundant Paths 分离的路径【边双模板】【傻逼题】

    LINK 经典傻逼套路 就是把所有边双缩点之后叶子节点的个数 //Author: dream_maker #include<bits/stdc++.h> using namespace s ...

  3. BZOJ 1718: [Usaco2006 Jan] Redundant Paths 分离的路径( tarjan )

    tarjan求边双连通分量, 然后就是一棵树了, 可以各种乱搞... ----------------------------------------------------------------- ...

  4. [Usaco2006 Jan] Redundant Paths 分离的路径

    1718: [Usaco2006 Jan] Redundant Paths 分离的路径 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1132  Solv ...

  5. BZOJ 1718: [Usaco2006 Jan] Redundant Paths 分离的路径

    Description 给出一个无向图,求将他构造成双连通图所需加的最少边数. Sol Tarjan求割边+缩点. 求出割边,然后缩点. 将双连通分量缩成一个点,然后重建图,建出来的就是一棵树,因为每 ...

  6. 【BZOJ】1718: [Usaco2006 Jan] Redundant Paths 分离的路径

    [题意]给定无向连通图,要求添加最少的边使全图变成边双连通分量. [算法]Tarjan缩点 [题解]首先边双缩点,得到一棵树(无向无环图). 入度为1的点就是叶子,两个LCA为根的叶子间合并最高效,直 ...

  7. bzoj 1718: [Usaco2006 Jan] Redundant Paths 分离的路径【tarjan】

    首先来分析一下,这是一张无向图,要求没有两条路联通的点对个数 有两条路连通,无向图,也就是说,问题转化为不在一个点双连通分量里的点对个数 tarjan即可,和求scc还不太一样-- #include& ...

  8. 【bzoj1718】Redundant Paths 分离的路径

    1718: [Usaco2006 Jan] Redundant Paths 分离的路径 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 964  Solve ...

  9. Redundant Paths 分离的路径【边双连通分量】

    Redundant Paths 分离的路径 题目描述 In order to get from one of the F (1 <= F <= 5,000) grazing fields ...

随机推荐

  1. vue.js之过渡动画

    vue提供了一个封装动画的组件 <transition name="tr"></transition>,将需要执行动画的元素包裹在该组件中,在通过css修改 ...

  2. poj2186--tarjan+缩点(有向图的强连通分量中点的个数)

    题目大意:       每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这 种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也 ...

  3. python 路径操作工具 pathlib,比 os 模块好用太多

    在 python 当中,如果你想控制路径,基本上绕不开 os.path.我希望看完这篇文章以后,熟练使用 python 的你能立刻开始使用 pathlib 模块,一刻也不要耽误. pathlib 相对 ...

  4. mac系统homebrew安装mysql

    homebrew 安装 mysql homebrew 是 macOS 缺失的软件包管理器,譬如可以下载 mysql.redis.wget 等等.操作系统:macOS High Sierra Versi ...

  5. js自执行函数

    5.1对于函数表达式,在后面加括号即可以让函数立即执行:例如下面这个函数,至于为什么加了括号就可以立即执行,我们可以这么理解,就是像fn1():这样写的话,函数 可以立即执行是没问题的,我们在经常会用 ...

  6. vue组件之间通信的8种方式

    对于vue来说,组件之间的消息传递是非常重要的,下面是我对组件之间消息传递的常用方式的总结. props和$emit(常用) $attrs和$listeners 中央事件总线(非父子组件间通信) v- ...

  7. Flask开发系列之模板

    Flask开发系列之模板 本文对<FlaskWeb开发:基于python的Web应用开发实战>模板一节做的总结. Jinja2模板引擎 模板 模板是一个包含响应文本的文件,其中包含用占位变 ...

  8. 搭建CocoaPods远程私有库

    1.创建自己的远程私有索引库,用来存放私有框架的.podspec文件,并将其添加到本地索引 我用的仓库是码云(https://gitee.com),用自己的账号新建一个私有仓库,我命名为Private ...

  9. 32-第3章 数据链路层--抓包分析数据帧格式-ISO一图了然-小结

    OSI理论模型 层级 名称 事物举例 功能 数据单位 别名 数据组成 协议举例 7 应用层 QQ.OA 网络通信 上层数据 上层数据 HTTP/FTP/DNS 6 表示层 web数据压缩.https加 ...

  10. Docker 镜像 容器 仓库

    Docker 包括三个基本概念镜像(Image)容器(Container)仓库(Repository) Docker 镜像 Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序.库.资 ...