题意抽象后为:
给定一个无向图

问添加一条边的情况下最少能有多少个桥。

桥的定义:删除该边后原图变为多个连通块。

数据规模:点数N(2<=N<=200000),边数M(1<=M<=1000000)

缩点之后求一下树的直径就好了,最优加边方案显然为连接直径的头尾。

AC代码:

#include<cstdio>
#include<cstring>
#include<queue>
#define rep(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
const int MAXV=;
const int MAXE=;
int DFN[MAXV],low[MAXV],par[MAXV],label[MAXV];
int pointer[MAXV];
int tot,cnt,m,n,Bcnt,ans;
vector<int> graph[MAXV];
int dep[MAXV];
struct Edge
{
int to,next;
bool vis;
Edge() {}
Edge(int b,int nxt,int flag) {to=b,next=nxt,vis=flag;}
}edge[MAXE];
inline void addedge(int a,int b)
{
edge[tot]=Edge(b,pointer[a],);
pointer[a]=tot++;
edge[tot]=Edge(a,pointer[b],);
pointer[b]=tot++;
}
void init()
{
tot=;
cnt=;Bcnt=;
memset(pointer,-,sizeof(pointer));
memset(label,,sizeof(label));
memset(DFN,,sizeof(DFN));
rep(i,,n)
{
graph[i].clear();
}
}
void tarjan(int u)
{
DFN[u]=low[u]=++cnt;
for(int j=pointer[u];j!=-;j=edge[j].next)
{
int v=edge[j].to;
if(edge[j].vis) continue;
edge[j].vis=edge[j^].vis=;
if(!DFN[v])
{
par[v]=j;
tarjan(v);
if(low[v]<low[u]) low[u]=low[v];
}
else if(low[u]>DFN[v]) low[u]=DFN[v];
}
}
void part(int u)
{
label[u]=Bcnt;
for(int j=pointer[u];j!=-;j=edge[j].next)
{
int v=edge[j].to;
if(!label[v]&&edge[j].vis) part(v);
}
}
void bfs(int s)
{
rep(i,,Bcnt) dep[i]=-;
queue<int > q;
dep[s]=;
q.push(s);
while(!q.empty())
{
int u=q.front();q.pop();
for(int j=;j<graph[u].size();++j)
{
int v=graph[u][j];
if(dep[v]==-)
{
dep[v]=dep[u]+;
q.push(v);
}
}
}
}
int diameter()
{
bfs();
int ma=,tag;
rep(i,,Bcnt)
{
if(dep[i]>ma)
{
tag=i;
ma=dep[i];
}
}
bfs(tag);
ma=;
rep(i,,Bcnt)
{
if(dep[i]>ma)
{
tag=i;
ma=dep[i];
}
}
return ma;
}
int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%d%d",&n,&m)==&&(n+m))
{
init();
int u,v;
rep(i,,m)
{
scanf("%d%d",&u,&v);
addedge(u,v);
}
tarjan();
int tmp;
rep(i,,n)
{
tmp=par[i]^;
u=edge[tmp].to;
if(low[i]>DFN[u])
{
edge[tmp].vis=;
edge[tmp^].vis=;
}
}
Bcnt=;
rep(i,,n)
{
if(!label[i])
{
Bcnt++;
part(i);
}
}
rep(i,,n)
{
if(!edge[par[i]].vis)
{
tmp=par[i]^;
u=edge[tmp].to;
graph[label[u]].push_back(label[i]);
graph[label[i]].push_back(label[u]);
}
}
printf("%d\n",Bcnt--diameter());
}
return ;
}

hdu4612 Warm up 缩点+树的直径的更多相关文章

  1. HDU4612:Warm up(缩点+树的直径)

    Warm up Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Su ...

  2. HDU4612 Warm up 边双(重边)缩点+树的直径

    题意:一个连通无向图,问你增加一条边后,让原图桥边最少 分析:先边双缩点,因为连通,所以消环变树,每一个树边都是桥,现在让你增加一条边,让桥变少(即形成环) 所以我们选择一条树上最长的路径,连接两端, ...

  3. hdu 4612 Warm up 有重边缩点+树的直径

    题目链接 Warm up Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Tot ...

  4. hdu4612(双连通缩点+树的直径)

    传送门:Warm up 题意:询问如何加一条边,使得剩下的桥的数目最少,输出数目. 分析:tarjan缩点后,重新建图得到一棵树,树上所有边都为桥,那么找出树的直径两个端点连上,必定减少的桥数量最多, ...

  5. hdu-4612(无向图缩点+树的直径)

    题意:给你n个点和m条边的无向图,问你如果多加一条边的话,那么这个图最少的桥是什么 解题思路:无向图缩点和树的直径,用并查集缩点: #include<iostream> #include& ...

  6. HDU 4612 Warm up (边双连通分量+缩点+树的直径)

    <题目链接> 题目大意:给出一个连通图,问你在这个连通图上加一条边,使该连通图的桥的数量最小,输出最少的桥的数量. 解题分析: 首先,通过Tarjan缩点,将该图缩成一颗树,树上的每个节点 ...

  7. F - Warm up HDU - 4612 tarjan缩点 + 树的直径 + 对tajan的再次理解

    题目链接:https://vjudge.net/contest/67418#problem/F 题目大意:给你一个图,让你加一条边,使得原图中的桥尽可能的小.(谢谢梁学长的帮忙) 我对重边,tarja ...

  8. codeforces GYM 100114 J. Computer Network 无相图缩点+树的直径

    题目链接: http://codeforces.com/gym/100114 Description The computer network of “Plunder & Flee Inc.” ...

  9. 【HDU 4612 Warm up】BCC 树的直径

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4612 题意:一个包含n个节点m条边的无向连通图(无自环,可能有重边).求添加一条边后最少剩余的桥的数 ...

随机推荐

  1. Mybaties 实现批量修改

    通常我们在做批量更新的时候都会用in 去操作,但in的数据量一上来,就变的缓慢了 修改方案: <update id="updateShufflingSeq" paramete ...

  2. 在Linux下OpenCV的下载和编译

    原理上来说,和windows下没有差别,我们同样使用Cmake-GUI来解决问题. 我们推荐QT和OpenCV全部采用官方的方式重新安装一遍,否则可能会丢失一些模块,而这些都会降低开发效率. 1.参考 ...

  3. vi删除当前行的字符

    x 删除当前光标下的字符dw 删除光标之后的单词剩余部分.d$ 删除光标之后的该行剩余部分.dd 删除当前行

  4. C#中get和set

    释一: 属性的访问器包含与获取(读取或计算)或设置(写)属性有关的可执行语句.访问器声明可以包含 get 访问器或 set 访问器,或者两者均包含.声明采用下列形式之一: get {} set {} ...

  5. HBase和MongoDB的区别

    Mongodb用于存储非结构化数据,尤其擅长存储json格式的数据.存储的量大概在10亿级别,再往上性能就下降了,除非另外分库.Hbase是架构在hdfs上的列式存储,擅长rowkey的快速查询,但模 ...

  6. oracle数据库 concat 与 ||

    1.简述: 通过几条sql语句来引入此问题 先新建一张表,插入几条数据,如下: CREATE TABLE tab1 (col1 VARCHAR2(6), col2 CHAR(6), col3 VARC ...

  7. script利用src引用外部js文件,如果内部嵌套了js代码呢

    <script src='test.js' defer async> var a = 5; </script> 这个时候 var a = 5;会被忽略.

  8. python模块--os模块

    打印文件的绝对路径:os.path.abspath(__file__) os.path.dirname("/root/python/test.py")   #只取目录名'/root ...

  9. Matlab:五点差分方法求解椭圆方程非导数边值问题

    差分格式脚本文件: tic; clear clc M=32;%x的步数 N=16;%y的步数 h1=1/M;%x的步长 h2=1/N;%y的步长 x=0:h1:1; y=0:h2:1; u=zeros ...

  10. OAF 抛出html消息

    throw new oracle.apps.fnd.framework.OAException("<html><p style=\"color:#FF0000; ...