Educational Codeforces Round 46 (Rated for Div. 2) E. We Need More Bosses(tarjan+树的直径)

耗尽温柔 提交于 2020-03-03 00:26:11

题目链接
在这里插入图片描述
在这里插入图片描述
题意:一条路径上必经的边为关键边,现在让你找一条路径,使得其关键边最多,输出最多的数量。
思路:先缩点,最多的边长肯定是树的直径,模板题。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll; 
const int maxn=3e5+10;
int a[maxn],b[maxn],low[maxn],dfn[maxn],vis[maxn],num[maxn],cnt=0,sum=0,maxx=0,id;
vector<int>g[maxn];
stack<int>s;
void tarjan(int x,int fa)
{
	low[x]=dfn[x]=++cnt;
	vis[x]=1;
	s.push(x);
	int flag=0;
	for(auto to:g[x])
	{
		if(to==fa){
			if(++flag<2) continue;
		}
		if(!dfn[to]) tarjan(to,x),low[x]=min(low[x],low[to]);
		else if(vis[to]) low[x]=min(low[x],low[to]);
	 } 
	 if(dfn[x]==low[x])
	 {
	 	int t;
	 	++sum;
	 	do{
	 		t=s.top();
	 		num[t]=sum;
	 		vis[t]=0;
	 		s.pop();
		 }while(t!=x);
	 }
}
void dfs(int x,int fa,int deep)
{
	if(deep>maxx) maxx=deep,id=x;
	for(auto to:g[x])
	{
	if(to==fa) continue;
	dfs(to,x,deep+1);
	}
}
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1,u,v;i<=m;++i)
	{
		scanf("%d%d",&u,&v);
		g[u].push_back(v);
		g[v].push_back(u);
		a[i]=u,b[i]=v;
	}
	tarjan(1,0);
	for(int i=1;i<=n;++i) g[i].clear();
	for(int i=1;i<=m;++i)
	if(num[a[i]]!=num[b[i]]) g[num[a[i]]].push_back(num[b[i]]),g[num[b[i]]].push_back(num[a[i]]);
	dfs(1,0,0);
	maxx=0;
	dfs(id,0,0);
	cout<<maxx<<endl;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!