【tarjan】【树的直径】【CF】K. Königsberg Bridges
作者:互联网
【tarjan】【树的直径】【CF】K. Königsberg Bridges
#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