Skip to content

Instantly share code, notes, and snippets.

@MinecraftFuns
Created November 19, 2020 11:01
Show Gist options
  • Save MinecraftFuns/1d8b590394f67fef9f7389c514cf345f to your computer and use it in GitHub Desktop.
Save MinecraftFuns/1d8b590394f67fef9f7389c514cf345f to your computer and use it in GitHub Desktop.
#include <bits/stdc++.h>
#define alive std::cout << "$LINE @" << __LINE__ << " ALIVE" << std::endl
#define watch(var) std::cout << "$ LINE @" << __LINE__ << " FUN @" << __FUNCTION__ \
<< " VAR @" << (#var) << ": " << (var) << std::endl
using namespace std;
typedef int i32;
typedef unsigned int u32;
typedef long long i64;
typedef unsigned long long u64;
typedef double f64;
typedef long double f128;
typedef pair<int, int> pii;
template <typename Tp>
inline void read(Tp &x)
{
x = 0;
bool neg = false;
char c = getchar();
for (; !isdigit(c); c = getchar())
{
if (c == '-')
{
neg = true;
}
}
for (; isdigit(c); c = getchar())
{
x = x * 10 + c - '0';
}
if (neg)
{
x = -x;
}
}
template <typename Tp>
inline Tp gcd(Tp n, Tp m)
{
while (m)
{
Tp t = n % m;
n = m;
m = t;
}
return n;
}
const int N = 2000 + 5;
int n, m;
int head[N], E = 1;
struct Edge
{
int to, next;
bool open;
} e[N * 2];
inline void addEdge(const int &u, const int &v)
{
e[++E] = (Edge){v, head[u], true};
head[u] = E;
}
inline void addE(const int &u, const int &v)
{
addEdge(u, v);
addEdge(v, u);
}
pii edge[N];
int dfn[N], low[N], tim = 0;
inline void clear()
{
memset(dfn + 1, 0, sizeof(int) * n);
memset(low + 1, 0, sizeof(int) * n);
tim = 0;
}
bool bridge[N];
void tarjan(int u, int fa)
{
dfn[u] = low[u] = ++tim;
for (int i = head[u], v; v = e[i].to, i; i = e[i].next)
{
if (v != fa && e[i].open)
{
if (!dfn[v])
{
tarjan(v, u);
low[u] = std::min(low[u], low[v]);
if (low[v] > dfn[u])
{
bridge[i >> 1] = true;
}
}
else
{
low[u] = std::min(low[u], dfn[v]);
}
}
}
}
void tarjan(int u, int fa, int &ans)
{
dfn[u] = low[u] = ++tim;
for (int i = head[u], v; v = e[i].to, i; i = e[i].next)
{
if (v != fa && e[i].open)
{
if (!dfn[v])
{
tarjan(v, u, ans);
low[u] = std::min(low[u], low[v]);
if (low[v] > dfn[u] && !bridge[i >> 1])
{
++ans;
}
}
else
{
low[u] = std::min(low[u], dfn[v]);
}
}
}
}
int main()
{
read(n), read(m);
for (int i = 1; i <= m; ++i)
{
int &u = edge[i].first, &v = edge[i].second;
read(u), read(v);
addE(u, v);
}
for (int i = 1; i <= n; ++i)
{
if (!dfn[i])
{
tarjan(i, 0);
}
}
int ans = 0;
for (int i = 1; i <= m; ++i)
{
if (!bridge[i])
{
e[i << 1].open = false;
e[i << 1 | 1].open = false;
clear();
int cur = 1;
for (int k = 1; k <= n; ++k)
{
if (!dfn[k])
{
tarjan(k, 0, cur);
}
}
ans = gcd(ans, cur);
e[i << 1].open = true;
e[i << 1 | 1].open = true;
}
}
for (int i = 1; i <= ans; ++i)
{
if (ans % i == 0)
{
printf("%d ", i);
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment