#pragma comment(linker,"/STACK:102400000,102400000")
#include <iostream>
#include <queue>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 200100;
const int maxm = 2000100;
struct node{
int v,next;
}edge[maxm];
struct Bridge
{
int u,v;
}bridge[maxm];
int head[maxn],vis[maxm],fa[maxn],dfn[maxn],low[maxn],stack[maxn],in[maxn];
int id,time,num,total,top,ans;
void add_edge(int u,int v)
{
edge[id].v = v;edge[id].next = head[u],head[u] = id++;
edge[id].v = u;edge[id].next = head[v],head[v] = id++;
}
int min(int x,int y)
{
return x < y ? x : y;
}
void tarjan(int u)
{//无向图找桥并缩点
low[u] = dfn[u] = ++time;
stack[top++] = u;
for(int id = head[u] ; id != -1; id = edge[id].next)
{
int v =edge[id].v;
if(vis[id])continue;
vis[id] = vis[id^1] = 1;
if( !dfn[v] )
{
tarjan(v);
low[u] = min(low[u],low[v]);
if( low[v] > dfn[u])//u经过v不能回到u,则u与v之间存在桥
{
bridge[total].u = u;
bridge[total++].v = v;
}
}
low[u] = min(low[u],dfn[v]);
}
if(low[u] == dfn[u])
{//对连通分量进行缩点
num++;
int t;
do{
t = stack[--top];
fa[t] = num;
}while( t != u);
}
}
vector<int>g[maxn]; int dfs(int u)
{//求树的最大直径
vis[u]=1;
int i,j,temp=0,Max=0,lMax=0;//Max为以u为根,u到的最远的叶子节点的距离,lMax为次最远距离
for(i = 0; i < g[u].size() ; i++ ){
int v = g[u][i];
if(vis[v])continue;
temp=dfs(v);
if(temp+1>=Max){
lMax=Max;
Max=temp+1;
}
else
if(temp+1>lMax)
lMax=temp+1;
if(Max+lMax>ans)
ans=Max+lMax;
}
return Max;
} int max_len()
{//求树的最大直径
int res = 0;
memset(vis,0,sizeof(vis));
queue<int>que;
que.push(1);
vis[1] = 1;
int tmp;
while( !que.empty())
{
int u = que.front();
que.pop();
tmp = u;
for( int i = 0 ; i < g[u].size(); i++)
{
int v = g[u][i];
if( vis[v] )continue;
vis[v] = 1;
que.push(v);
}
} queue<pair<int,int> >que1;
memset(vis,0,sizeof(vis));
que1.push(make_pair(tmp,0));
pair<int,int>x,y;
vis[tmp] = 1;
while( !que1.empty())
{
x = que1.front();
que1.pop();
for(int i = 0; i < g[x.first].size() ; i++)
{
int v = g[x.first][i];
if( vis[v] )continue;
vis[v] = 1;
que1.push(make_pair(v,x.second+1));
res = res > x.second ? res : x.second + 1;
}
}
return res;
}
int main()
{
int n,m,u,v;
int i;
// freopen("in.txt","r",stdin);
while( ~scanf("%d%d",&n,&m) && n+m)
{
id = 0;
memset(head,-1,sizeof(head));
while( m-- )
{
scanf("%d%d",&u,&v);
add_edge(u,v);
}
total = num = 0;
memset(dfn,0,sizeof(dfn));
memset(fa,-1,sizeof(fa));
memset(vis,0,sizeof(vis));
for(i = 1; i <= n; i++)//可以处理不连通的无向图,如果连通只需要一次即可
{
if( !dfn[i] )
{
top = time = 1;
tarjan(i);
//num++;
//for( int j = 1; j <= n; j++) //特殊处理顶点的连通块
// if( dfn[j] && fa[j] == -1)fa[j] = num;
}
}
//for( i = 1; i <= n; i++)cout << fa[i] << endl;
for(i = 1; i <= n;i++)g[i].clear();
int x,y;
//建树
// cout << total << endl;
for( i = 0 ; i < total; i++)
{
x = fa[bridge[i].u];
y = fa[bridge[i].v];
//cout << x << " " << y << endl;
g[x].push_back(y);
g[y].push_back(x);
}
memset(vis,0,sizeof(vis));
ans = 0;
dfs(1);
printf("%d\n",total - ans );
}
return 0;
}

  

  

hdu 4612 无向图连通分量缩点,然后求树的最大直径的更多相关文章

  1. hdu 4612 双联通缩点+树形dp

    #pragma comment(linker,"/STACK:102400000,102400000")//总是爆栈加上这个就么么哒了 #include<stdio.h> ...

  2. HDU-4612 Warm up,tarjan求桥缩点再求树的直径!注意重边

    Warm up 虽然网上题解这么多,感觉写下来并不是跟别人竞争访问量的,而是证明自己从前努力过,以后回头复习参考! 题意:n个点由m条无向边连接,求加一条边后桥的最少数量. 思路:如标题,tarjan ...

  3. HDU4612+Tarjan缩点+BFS求树的直径

    tarjan+缩点+树的直径题意:给出n个点和m条边的图,存在重边,问加一条边以后,剩下的桥的数量最少为多少.先tarjan缩点,再在这棵树上求直径.加的边即是连接这条直径的两端. /* tarjan ...

  4. HDU 4607 Park Visit 两次DFS求树直径

    两次DFS求树直径方法见 这里. 这里的直径是指最长链包含的节点个数,而上一题是指最长链的路径权值之和,注意区分. K <= R: ans = K − 1; K > R:   ans = ...

  5. HDU 4607 Park Visit 树的最大直径

    题意: 莱克尔和她的朋友到公园玩,公园很大也很漂亮.公园包含n个景点通过n-1条边相连.克莱尔太累了,所以不能去参观所有点景点. 经过深思熟虑,她决定只访问其中的k个景点.她拿出地图发现所有景点的入口 ...

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

    思路:强连通分量缩点,建立一颗新的树,然后求树的最长直径,然后加上一条边能够去掉的桥数,就是直径的长度. 树的直径长度的求法:两次bfs可以求,第一次随便找一个点u,然后进行bfs搜到的最后一个点v, ...

  7. hdoj 4612 Warm up【双连通分量求桥&&缩点建新图求树的直径】

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

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

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

  9. HDU 4612——Warm up——————【边双连通分量、树的直径】

    Warm up Time Limit:5000MS     Memory Limit:65535KB     64bit IO Format:%I64d & %I64u Submit Stat ...

随机推荐

  1. java流压缩图片

    整理文档,搜刮出一个Java做图片压缩的代码,稍微整理精简一下做下分享.首先,要压缩的图片格式不能说动态图片,你可以使用bmp.png.gif等,至于压缩质量,可以通过BufferedImage来指定 ...

  2. Vue2.0仿饿了么webapp单页面应用

    Vue2.0仿饿了么webapp单页面应用 声明: 代码源于 黄轶老师在慕课网上的教学视频,我自己用vue2.0重写了该项目,喜欢的同学可以去支持老师的课程:http://coding.imooc.c ...

  3. 4. 源码分析---SOFARPC服务端暴露

    服务端的示例 我们首先贴上我们的服务端的示例: public static void main(String[] args) { ServerConfig serverConfig = new Ser ...

  4. k8s学习02-----kubeadm部署k8s

    机器规划 系统配置 三台机器都执行 1.关闭selinux及firewalld sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux ...

  5. 【Java笔记】【Java核心技术卷1】chapter3 D5运算符

    package chapter3; import java.math.*; //引入数学类 //枚举类型 enum Size{SMALL,MEDIUM,LARGE}; public class D5运 ...

  6. 8.源码分析---从设计模式中看SOFARPC中的EventBus?

    我们在前面分析客户端引用的时候会看到如下这段代码: // 产生开始调用事件 if (EventBus.isEnable(ClientStartInvokeEvent.class)) { EventBu ...

  7. Mermaid

    graph TD; A-->B; A-->C; B-->D; C-->D;

  8. 洛谷 P2657 [SCOI2009]windy数

    题意简述 求l~r之间不含前导零且相邻两个数字之差至少为2的正整数的个数 题解思路 数位DP 代码 #include <cstdio> #include <cstring> # ...

  9. nginx 使用HTTPS协议-SSL证书模块报错解决-附nginx安装 : [emerg] the "ssl" parameter requires ngx_http_ssl_module in nginx.c

    Linux系统下ngnix使用HTTPS协议启动报错: nginx: [emerg] the "ssl" parameter requires ngx_http_ssl_modul ...

  10. Kubernetes-保障集群内节点和网络安全

    13.1.在pod中使用宿主节点的Linux命名空间 13.1.1.在pod中使用宿主节点的网络命名空间 在pod的yaml文件中就设置spec.hostNetwork: true 这个时候pod使用 ...