#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. BME200加密网关,在电力与工业应用的加密网关设计与介绍

    加密通信网关,顾名思义就是带加密的通信网关终端,  一般业内主是需用到是工业通信关行业的为主的.,BME200加密通信网关,主要电力和工业互联网相关领域开发的一款加密通信网关. 为什么出现加密网关 1 ...

  2. Golang版本的rocksdb-对gorocksdb的封装

    rocksdb的优秀特性不用多说,但是它是用c++语言写的,就是这一个特点就把很多人拦住了.虽然rocksdb官方也有Java版本,但是Golang的发展速度让人不容小觑,而且由于golang原生对高 ...

  3. Where is the clone one and how to extract it?

    One cannot be in two places at once. Do you know what's "Dual Apps"? Manufactures like Xia ...

  4. Java----面向对象(继承&多态)

    一.继承 什么是继承 ? 让类与类之间产生了子父类关系 ; 继承的好处是: 提高代码的复用性和维护性 java中继承的特点是: 只支持单继承.不支持多继承,但是可以多层继承; 四种权限修饰符是 : p ...

  5. c#将字符串转化为合理的文件名

    string name = System.Text.RegularExpressions.Regex.Replace(url, "[<>/\\|:\"?*]" ...

  6. 关于dfs的套路

    void dfs(答案, 搜索层数, 其他参数) { if (层数==maxdeep) { 更新答案 return; } (剪枝) for(下一层可能的状态){ 更新全局变量表示的状态的变量 dfs( ...

  7. javaweb基础整理随笔------jstl与el表达式

    虽然jsp中可以写java代码,但是现在不推荐这么做. jsp虽然本质是servlet,但是主要作用只是视图,视图的任务就是显示响应,而不是在JSP中做任何关于程序控制和业务逻辑的事情.所以在JSP页 ...

  8. android ——Toolbar

    Toolbar是我看material design内容的第一个 官方文档:https://developer.android.com/reference/android/support/v7/widg ...

  9. Knative 基本功能深入剖析:Knative Serving 之服务路由管理

    导读:本文主要围绕 Knative Service 域名展开,介绍了 Knative Service 的路由管理.文章首先介绍了如何修改默认主域名,紧接着深入一层介绍了如何添加自定义域名以及如何根据 ...

  10. 如何使用Python连接ldap

    如何使用Python连接ldap 好多使用ldap认证的软件都是Python的,比如superset和airflow, 好吧,他们都是airbnb家的.在配置ldap的时候可能会出现认证失败,你不知道 ...