其他分享
首页 > 其他分享> > 【tarjan】【树的直径】【CF】K. Königsberg Bridges

【tarjan】【树的直径】【CF】K. Königsberg Bridges

作者:互联网

【tarjan】【树的直径】【CF】K. Königsberg Bridges

image

题目传送门

#include <bits/stdc++.h>
#define MEM(a,x) memset(a,x,sizeof(a))
#define W(a) while(a)
#define gcd(a,b) __gcd(a,b)
#define pi acos(-1.0)
#define PII pair<int,int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ll long long
#define ull unsigned long long
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define MAX 1000005
#define MOD 1000000007
#define INF 0x3f3f3f3f
#define lowbit(x) (x&-x)
#define de(x) cout<<"debug : "<<x<<endl
using namespace std;
inline int read()
{
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0' && ch<='9')
        x=x*10+ch-'0',ch=getchar();
    return x*f;
}
const int N = 1E6+100, M = 2E6+100;
struct edge{
	int u,v,nxt;
}edges[M],edges_scc[M];

int idx,h[N];
void add_edge(int u,int v) 
{
	edges[idx] = {u,v,h[u]};
	h[u] = idx++;
}

int idx_scc,h_scc[N];
void add_scc(int u,int v)
{
	edges_scc[idx_scc] = {u,v,h_scc[u]};
	h_scc[u] = idx_scc++;
}
int low[N],dfn[N],time_stamp,scc_cnt,bel[N];
bool in_st[N],is_bridge[M];
stack<int > st;
vector<int > scc[N];
void tarjan(int u,int from)
{

	dfn[u] = low[u] = ++time_stamp;
        in_st[u] = true;
	st.push(u);
	for(int i = h[u];~i;i=edges[i].nxt)
	{
		int v = edges[i].v;
	  
		if(!dfn[v])
		{ 
			tarjan(v,i);
			low[u] = min(low[v],low[u]);
			if(dfn[u]<low[v])
			   is_bridge[i] = is_bridge[i^1] = 1;
		}
		else if(i!=(from^1))
		    low[u] = min(low[v],low[u]);
	}
	if(dfn[u]==low[u])
	{
		int t;
	        do{
			t = st.top();
			st.pop();
			in_st[t] = false;
			scc[scc_cnt].push_back(t);
			bel[t] = scc_cnt;
		}while(t!=u);
		scc_cnt++;
	}
}
int max_len,max_v;
bool used[N];
void dfs(int u,int fa,int dep)
{
	used[u] = true;
	if(dep>max_len)
	{
		max_v = u;
		max_len = dep;	
	}
	for(int i = h_scc[u];~i;i=edges_scc[i].nxt)
	{
		if(edges_scc[i].v==fa) continue;
		dfs(edges_scc[i].v,u,dep+1);
	}
}
int main()
{
	int n = read(),m = read();
	memset(h,-1,sizeof(h));
	memset(h_scc,-1,sizeof(h_scc));

	for(int i=0;i<m;i++)
	{
		int u = read(),v = read();
		add_edge(u,v);add_edge(v,u);
	}

	for(int i=0;i<n;i++)
	    if(!dfn[i])
	       tarjan(i,-1);
     
	for(int i=0;i<idx;i+=2)
	   if(is_bridge[i])
	   	  add_scc( bel[edges[i].u], bel[edges[i].v] ),add_scc( bel[edges[i].v],bel[edges[i].u]);
	
    int ans = 0,blocks = 0;
    for(int i=0;i<scc_cnt;i++)
    {
    	if(!used[i])
    	{
    		blocks ++;
    		max_len = 0,max_v = i;//直径的点要初始化好,不然还是停留在上一轮 
    		dfs(i,-1,0);
    		max_len = 0;
     		dfs(max_v,-1,0);
    		ans += max_len;
		}
	}
	cout<<ans+blocks-1;
        return 0;
}

标签:Bridges,tarjan,ch,int,scc,edges,nigsberg,define
来源: https://www.cnblogs.com/BeautifulWater/p/15549482.html