题目链接

https://www.luogu.org/problemnew/show/P2860

https://www.lydsy.com/JudgeOnline/problem.php?id=1718

分析

首先这题目的意思就是让任意两点之间至少有两条没有重复道路的路径,很显然,如果这个图不存在桥,就一定满足上述条件。

于是我们就是要求使这个图不存在桥需要连接的最小边数

如果把桥从图中去掉,很显然剩余的联通块中任意两点之间至少有两条没有重复道路的路径(当然也可能不是联通块而是孤立的点),对答案不会产生贡献,我们不妨就将这些联通块缩点,于是就原来的图就变成了一颗树。

然后思考题目要求,当每个节点的度为2时任意两点之间至少有两条没有重复道路的路径,因为此时任意节点都有两条不同道路可走,于是用贪心的思想我们让度数为\(1\)的先互相连接,所以计算出树中的叶节点个数\(x\),\(\lceil\frac{x}{2}\rceil\)就是答案

注意

好象没什么注意的,不过我太菜把\(edge [j] .to\)写成\(edge [i] .to\)查了好久的错

代码


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <cctype>
#include <cmath>
#include <map>
#include <queue>
#define ll long long
#define ri register int
using namespace std;
const int maxn=5005;
const int maxm=10005;
const int inf=0x7fffffff;
template <class T>inline void read(T &x){
x=0;int ne=0;char c;
while(!isdigit(c=getchar()))ne=c=='-';
x=c-48;
while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48;
x=ne?-x:x;
return ;
}
struct Edge{
int ne,to;
}edge[maxm<<1];
int h[maxn],num_edge=0;
inline void add_edge(int f,int to){
edge[++num_edge].ne=h[f];
edge[num_edge].to=to;
h[f]=num_edge;
return ;
}
int n,m;
int dfn[maxn],low[maxn],tot=0;
bool bridge[maxm];
void tarjan(int now,int in_edge){//所在边的标号
int v;dfn[now]=low[now]=++tot;
for(ri i=h[now];i;i=edge[i].ne){
v=edge[i].to;
if(!dfn[v]){
tarjan(v,i);
low[now]=min(low[now],low[v]);
if(dfn[now]<low[v]){
bridge[i]=bridge[i^1]=true;//是桥
bb++;
}
}
else if(i!=(in_edge^1)){//如果不是在同一条无向边的对应边
low[now]=min(low[now],dfn[v]);
}
}
return ;
}
int num=0;//联通块的数量
int in_block[maxn];//各点所在联通块的标号
bool g[maxn][maxn];//重构后的图(储存)
void Contraction_Point(int now){//缩点
int v;in_block[now]=num;
for(ri i=h[now];i;i=edge[i].ne){
v=edge[i].to;
if(!bridge[i]&&!in_block[v]){
Contraction_Point(v);
}
}
return ;
}
int du[maxn];
inline void solve(){
int ans=0,x,y;
memset(g,0,sizeof(g));
for(ri i=1;i<=n;i++){
x=in_block[i];
for(ri j=h[i];j;j=edge[j].ne){
y=in_block[edge[j].to]; //太坑了
g[x][y]=g[y][x]=1;
}
}
memset(du,0,sizeof(du));
for(ri i=1;i<=num;i++){
for(ri j=1;j<=num;j++){
if(i!=j&&g[i][j]){du[j]++;
}
}
}
for(ri i=1;i<=num;i++){
if(du[i]==1)ans++;
}
printf("%d",(int)ceil(ans/double(2)));
return ;
}
int main(){
int x,y;
read(n),read(m);
num_edge=1;
for(ri i=1;i<=m;i++){
read(x),read(y);
add_edge(x,y);
add_edge(y,x);
}
memset(bridge,0,sizeof(bridge));
tarjan(1,0);
memset(in_block,0,sizeof(in_block));
for(ri i=1;i<=n;i++){
if(!in_block[i]){
num++;
Contraction_Point(i);
}
}
solve();
return 0;
}

luogu题解 P2860[USACO冗余路径Redundant Paths] 缩点+桥的更多相关文章

  1. 洛谷 P2860 [USACO06JAN]冗余路径Redundant Paths 解题报告

    P2860 [USACO06JAN]冗余路径Redundant Paths 题目描述 为了从F(1≤F≤5000)个草场中的一个走到另一个,贝茜和她的同伴们有时不得不路过一些她们讨厌的可怕的树.奶牛们 ...

  2. 【luogu P2860 [USACO06JAN]冗余路径Redundant Paths】 题解

    题目链接:https://www.luogu.org/problemnew/show/P2860 考虑在无向图上缩点. 运用到边双.桥的知识. 缩点后统计度为1的点. 度为1是有一条路径,度为2是有两 ...

  3. luogu P2860 [USACO06JAN]冗余路径Redundant Paths

    题目描述 In order to get from one of the F (1 <= F <= 5,000) grazing fields (which are numbered 1- ...

  4. luogu P2860 [USACO06JAN]冗余路径Redundant Paths |Tarjan

    题目描述 In order to get from one of the F (1 <= F <= 5,000) grazing fields (which are numbered 1. ...

  5. LUOGU P2860 [USACO06JAN]冗余路径Redundant Paths (双联通,缩点)

    传送门 解题思路 刚开始是找的桥,后来发现这样不对,因为一条链就可以被卡.后来想到应该缩点后找到度数为1 的点然后两两配对. #include<iostream> #include< ...

  6. 洛谷P2860 [USACO06JAN]冗余路径Redundant Paths(tarjan求边双联通分量)

    题目描述 In order to get from one of the F (1 <= F <= 5,000) grazing fields (which are numbered 1. ...

  7. P2860 [USACO06JAN]冗余路径Redundant Paths tarjan

    题目链接 https://www.luogu.org/problemnew/show/P2860 思路 缩点,之后就成了个树一般的东西了 然后(叶子节点+1)/2就是答案,好像贪心的样子,lmc好像讲 ...

  8. 洛谷P2860 [USACO06JAN]冗余路径Redundant Paths

    题目描述 In order to get from one of the F (1 <= F <= 5,000) grazing fields (which are numbered 1. ...

  9. (精)题解 guP2860 [USACO06JAN]冗余路径Redundant Paths

    (写题解不容易,来我的博客玩玩咯qwq~) 该题考察的知识点是边双连通分量 边双连通分量即一个无向图中,去掉一条边后仍互相连通的极大子图.(单独的一个点也可能是一个边双连通分量) 换言之,一个边双连通 ...

随机推荐

  1. postman设置环境变量,实现一套接口根据选择的环境去请求不同的url

    一个系统,有本地,开发,测试,生产等不同的环境,如果写不同的url配置多套会比较麻烦,可以设置不同的环境实现不同的url之间的切换.配置之后如下: 第一步: 第二步: 添加环境变量 ps::不同的环境 ...

  2. ORACLE数据库黑/白名单

    编辑sqlnet.ora文件 #开启ip限制功能tcp.validnode_checking=yes#允许访问数据库的IP地址列表,多个IP地址使用逗号分开tcp.invited_nodes=(10. ...

  3. PCB Layout初学者必会知识总结(转)

    PCB是印刷电路板(即Printed Circuit Board)的简称.印刷电路板是组装电子零件用的基板,是在通用基材上按预定设计形成点间连接及印制元件的印制板.该产品的主要功能是使各种电子零组件形 ...

  4. 一个伪静态与404重定向例子(房产网),.htaccess文件内容

    ErrorDocument 404 /404.phpRewriteEngine OnRewriteBase /RewriteRule ^(.*)\.(asp|aspx|asa|asax|dll|jsp ...

  5. 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_3-5.PageHelper分页插件使用

    笔记 5.PageHelper分页插件使用     简介:讲解开源组件,mybaits分页插件的使用 1.引入依赖             <!-- 分页插件依赖 -->          ...

  6. 在Python中使用glob模块查找文件路径的方法

    在Python中使用glob模块查找文件路径的方法 glob模块是最简单的模块之一,内容非常少.用它可以查找符合特定规则的文件路径名.跟使用windows下的文件搜索差不多.查找文件只用到三个匹配符: ...

  7. 转:SpringMVC 4.1 新特性(二)内容协商视图

    SpingMVC的内容协商支持三种方式: 使用后缀,如json.xml后缀和处理类型的关系可以自己定义 前面说的使用Accept头 在访问时request请求的参数,比如每次请求request都会加f ...

  8. Unity3D热更新之LuaFramework篇[04]--自定义UI监听方法

    时隔一个多月我又回来啦! 坚持真的是很难的一件事,其它事情稍忙,就很容易说服自己把写博客的计划给推迟了. 好在终于克服了自己的惰性,今天又开始了. 本篇继续我的Luaframework学习之路. 一. ...

  9. Leetcode之动态规划(DP)专题-122. 买卖股票的最佳时机 II(Best Time to Buy and Sell Stock II)

    Leetcode之动态规划(DP)专题-122. 买卖股票的最佳时机 II(Best Time to Buy and Sell Stock II) 股票问题: 121. 买卖股票的最佳时机 122. ...

  10. Java垃圾收集器与内存分配策略

    程序的计数器.虚拟机栈.本地方法栈3个区域随线程而生,随线程而灭:栈中的栈侦随着方法的进入和退出而有条不紊地执行出栈和如栈操作. 判断对象是不是已经死亡的方法: 一.引用计数算法: 给对象添加一个引用 ...