Your friend is developing a computer game. He has already decided how the game world should look like — it should consist of nn locations connected by mm two-way passages. The passages are designed in such a way that it should be possible to get from any location to any other location.
Of course, some passages should be guarded by the monsters (if you just can go everywhere without any difficulties, then it's not fun, right?). Some crucial passages will be guarded by really fearsome monsters, requiring the hero to prepare for battle and designing his own tactics of defeating them (commonly these kinds of monsters are called bosses). And your friend wants you to help him place these bosses.
The game will start in location ss and end in location tt, but these locations are not chosen yet. After choosing these locations, your friend will place a boss in each passage such that it is impossible to get from ss to tt without using this passage. Your friend wants to place as much bosses as possible (because more challenges means more fun, right?), so he asks you to help him determine the maximum possible number of bosses, considering that any location can be chosen as ss or as tt.
The first line contains two integers nn and mm (2≤n≤3⋅1052≤n≤3⋅105, n−1≤m≤3⋅105n−1≤m≤3⋅105) — the number of locations and passages, respectively.
Then mm lines follow, each containing two integers xx and yy (1≤x,y≤n1≤x,y≤n, x≠yx≠y) describing the endpoints of one of the passages.
It is guaranteed that there is no pair of locations directly connected by two or more passages, and that any location is reachable from any other location.
Print one integer — the maximum number of bosses your friend can place, considering all possible choices for ss and tt.
2
3
今天终于给这道图论题一下子干倒了。。。今天对着题纳闷了很久,什么叫maximum,每条路都放上一个怪兽不就行了。。。后来经大佬指点,约莫是说,是要对求过割边的图进行缩点,之后剩下的路全是可以放怪兽的路,然后对缩点形成的树进行一番求直径。那么就这么办吧。今天写的这个缩点和我以前的习惯不大一样,每次cnt加一在进行dfs,遇到桥,就对所点以后的图添加边,否则把新点加到当前的集合里。
代码丑恶得一匹。。。
#include<iostream>
#include<cstdio>
#include<string.h>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=300005;
const int maxm=300005;
vector<int> vec[300005];
int dis[300005];
int part[300005];
int tmp[300005];
int maxx=0;
struct Edge
{
int to,next;
bool cut;
}edge[2*maxm];
int head[maxn],tot;
int low[maxn],dfn[maxn],stack[maxn];
int index,top;
bool instack[maxn];
int bridge;
int cnt=0;
void addedge(int u,int v)
{
edge[tot].to=v; edge[tot].next=head[u]; edge[tot].cut=false;
head[u]=tot++;
}
void tarjan(int u,int pre)
{
//cout<<"u="<<u<<endl;
int v;
low[u] = dfn[u] = ++index;
stack[top++] = u;
instack[u] = true;
int son = 0; int pre_num=0;
for(int i = head[u];i != -1;i = edge[i].next)
{
v = edge[i].to;
//cout<<"v="<<v<<endl;
if (v==pre&&!pre_num)
{
pre_num++; continue;
}
if( !dfn[v] )
{
son++;
tarjan(v,u);
if(low[u] > low[v])low[u] = low[v];
//桥
//一条无向边(u,v)是桥,当且仅当(u,v)为树枝边,且满足DFS(u)<Low(v)。
if(low[v] > dfn[u])
{
bridge++;
edge[i].cut = true;
edge[i^1].cut = true;
}
}
else if( low[u] > dfn[v])
low[u] = dfn[v];
}
//树根,分支数大于1
instack[u] = false;
top--;
}
void solve(int n)
{
memset(dfn,0,sizeof(dfn));
memset(instack,false,sizeof(instack));
index=top=0;
bridge=0;
for (int i=1; i<=n; i++)
{
if (!dfn[i]) tarjan(i,i);
}
}
void init()
{
tot=0;
memset(head,-1,sizeof(head));
}
int sum=0;
void dfs1(int u,int pre)
{
//cout<<"u="<<u<<" cnt="<<cnt<<endl;
part[u]=cnt;
for(int i = head[u];i != -1;i = edge[i].next)
{
int v=edge[i].to;
//cout<<"v="<<v<<endl;
if (edge[i].cut)
{
//cout<<"yes"<<endl;
if (part[v]!=-1 && tmp[v]!=cnt)
{
tmp[v]=cnt;
vec[cnt].push_back(part[v]);
vec[part[v]].push_back(cnt);
//cout<<"cnt="<<cnt<<" part="<<part[v]<<endl;
}
}
else if (part[v]==-1)
dfs1(v,u);
}
}
void dfs2(int u,int pre)
{
for (int i=0; i<vec[u].size(); i++)
{
int v=vec[u][i];
if (v==pre) continue;
dfs2(v,u);
if (dis[v]+1+dis[u]>maxx)
maxx=dis[v]+1+dis[u];
if (dis[v]+1>dis[u])
dis[u]=dis[v]+1;
}
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
init();
for (int i=1; i<=m; i++)
{
int a,b; scanf("%d%d",&a,&b);
addedge(a,b);
addedge(b,a);
}
solve(n);
memset(part,-1,sizeof(part));
for (int i=1; i<=n; i++)
{
if (part[i]==-1)
{
cnt++,dfs1(i,0);
}
}
memset(dis,0,sizeof(dis));
dfs2(1,0);
cout<<maxx<<endl;
return 0;
}