zoukankan      html  css  js  c++  java
  • CF1000E We Need More Bosses [缩点,直径]

    根据强连通分量的性质,对于 (u,vin 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)] = '
    '; }
    	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 << '
    ';
      return 0;
    }
    
  • 相关阅读:
    每天一个linux命令(20):linux chmod命令
    每天一个linux命令(19):Linux 目录结构
    每天一个linux命令(18):find 命令概览
    每天一个linux命令(17):locate 命令
    shiro实战系列(一)之入门实战
    nginx反向代理和tomcat集群(适用于ubutnu16.04及其centos7)
    Ubuntu16.04之开发环境构建
    Drools实战系列(三)之eclipse创建工程
    Drool实战系列(二)之eclipse安装drools插件
    谈谈maven多模块
  • 原文地址:https://www.cnblogs.com/Isaunoya/p/12818940.html
Copyright © 2011-2022 走看看