HDU 4612 Warm up(手动扩栈,求树上哪两个点的距离最远)

时间:2023-03-10 01:03:19
HDU 4612 Warm up(手动扩栈,求树上哪两个点的距离最远)
题目大意:
给你一个无向图,问加一条边之后最少还剩下几座桥。
(注意重边处理)
分析:其实当我们把边双连通分量给求出来之后我们就能将连通块求出来,这样我们就可以重新构图。重新构造出来的图肯定是一颗树了,
那么问题就转化为求树的哪两个节点的距离最长。我们可以随便找一个点S开始BFS, BFS到这个点最远的那个点P,然后再从这个最远点P开始BFS,BFS到P最远的点E,  PE之间的距离就是这个图上最大的距离。
注:此题需要手动扩栈
#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
#include <stack>
#include <cstring>
usingnamespace std;
#define INF 0xfffffff
#define maxn 200005
#define min(a,b) (a<b?a:b)
int m, n, Time, top, cnt;
int blocks[maxn], dfn[maxn], low[maxn], Stacks[maxn], Father[maxn];
int step[maxn];
vector<vector<int> > G;
vector<vector<int> > G2;
void init()
{
memset(dfn, , sizeof(dfn));
memset(low, , sizeof(low));
memset(blocks, , sizeof(blocks));
Time = top = cnt = ;
G.clear();
G.resize(n+); G2.clear();
G2.resize(n+);
}
void Tarjan(int u,int fa)
{
dfn[u] = low[u] = ++Time;
Stacks[top ++] = u;
Father[u] = fa;
int len = G[u].size(), k = , v; for(int i=; i<len; i++)
{
v = G[u][i]; if( !k && fa == v)
{
k ++;
continue;
} if( !low[v] )
{
Tarjan(v, u);
low[u] = min(low[u], low[v]);
}
else
low[u] = min(low[u], dfn[v]);
} if(dfn[u] == low[u])
{
do
{
v = Stacks[--top];
blocks[v] = cnt;
}while(u != v);
cnt ++;
}
}
int BFS(int s,int flag)
{
int P, Pn;
queue<int> Q;
Q.push(s);
memset(step, -, sizeof(step));
step[s] = ;
while( Q.size() )
{
P = Q.front();
Q.pop(); int len = G2[P].size(); for(int i=; i<len; i++)
{
Pn = G2[P][i]; if( step[Pn] == -)
{
step[Pn] = step[P] + ;
Q.push(Pn);
}
}
} if(flag == )
return P;
return step[P];
}
void solve()
{
int ans = , i;
for(i=; i<=n; i++)
{
if(!low[i])
Tarjan(i, i);
} for(i=; i<=n; i++)
{
int v = Father[i]; if(blocks[i] != blocks[v])
{ /**重新构图*/
G2[blocks[i] ].push_back(blocks[v]);
G2[blocks[v] ].push_back(blocks[i]);
}
} int p = BFS(,);///以0为起点经行一次BFS返回最远距离的编号 ans = cnt - BFS(p, ) - ;///返回最远距离的长度
printf("%d\n", ans); } int main()
{
while(scanf("%d %d",&n, &m), m+n)
{
init();
while(m--)
{
int a, b;
scanf("%d %d",&a, &b);
G[a].push_back(b);
G[b].push_back(a);
}
solve();
}
return0;
}
/*
5 4
1 2
1 3
1 4
2 5
*/