码迷,mamicode.com
首页 > 其他好文 > 详细

CF1000E We Need More Bosses [缩点,直径]

时间:2020-05-02 18:51:42      阅读:43      评论:0      收藏:0      [点我收藏+]

标签:ace   read   include   this   强连通   second   efi   tarjan   std   

根据强连通分量的性质,对于 \(u,v\in V\)\(u\) 可以到达 \(v\)\(v\) 可以到达 \(u\)

显然同一个强连通分量的不是必经边,所以缩完搞个直径就完事了。

#include <bits/stdc++.h>
#define int long long
using namespace std;
struct io {
	char buf[1 << 26 | 3], *s; int f;
	io() { f = 0, buf[fread(s = buf, 1, 1 << 26, stdin)] = ‘\n‘; }
	io& operator >> (int&x) {
		for(x = f = 0; !isdigit(*s); ++s) f |= *s  == ‘-‘;
		while(isdigit(*s)) x = x * 10 + (*s++ ^ 48);
		return x = f ? -x : x, *this;
	}
};

int n, m;
const int maxn = 3e5 + 53;
struct edge {
  int v, nxt;
} e[maxn << 1];
int head[maxn], cnt = 0;
void add(int u, int v) { e[++ cnt] = { v , head[u] } , head[u] = cnt; }
int st[maxn], top = 0;
int dfn[maxn], low[maxn], idx = 0;
int col[maxn], c = 0;
void tarjan(int u, int f) {
  dfn[u] = ++ idx, low[u] = dfn[u];
  st[++ top] = u;
  for(int i = head[u]; i; i = e[i].nxt) {
    int v = e[i].v;
    if(v == f) continue;
    if(!dfn[v]) tarjan(v, u), low[u] = min(low[u], low[v]);
    else if(!col[v]) low[u] = min(low[u], dfn[v]);
  }
  if(low[u] == dfn[u]) {
    ++c;
    while(st[top + 1] ^ u) { col[st[top --]] = c; }
  }
}

vector <int> g[maxn];
int dep[maxn];

void dfs(int u, int fa) {
  dep[u] = dep[fa] + 1;
  for(int v : g[u]) {
    if(v ^ fa)
      dfs(v, u);
  }
}

#define out cout
signed main() {
#ifdef LOCAL
#define in cin
  ios :: sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
  freopen("testdata.in", "r", stdin);
#else
  io in;
#endif
  in >> n >> m;
  vector<pair<int, int>> E;
  for(int i = 0 ; i < m ; i ++) {
    int u, v; in >> u >> v;
    add(u, v), add(v, u);
    E.push_back({u, v});
  }
  for(int i = 1 ; i <= n ; i ++) {
    if(! dfn[i]) tarjan(i, 0);
  }
  for(auto x : E) {
    int u = x.first, v = x.second;
    if(col[u] ^ col[v]) {
      g[col[u]].push_back(col[v]);
      g[col[v]].push_back(col[u]);
    }
  }
  int rt;
  rt = 1;
  dfs(rt, 0);
  int mx = 1;
  for(int i = 1 ; i <= n ; i ++) if(dep[mx] < dep[i]) mx = i;
  rt = mx;
  dfs(rt, 0); mx = 0;
  for(int i = 1 ; i <= n ; i ++) mx = max(dep[i], mx);
  out << mx - 1 << ‘\n‘;
  return 0;
}

CF1000E We Need More Bosses [缩点,直径]

标签:ace   read   include   this   强连通   second   efi   tarjan   std   

原文地址:https://www.cnblogs.com/Isaunoya/p/12818940.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!