原题链接
很水的一道题,先用(tarjan)找边双连通分量并缩点,因为缩点后必然是一棵树,所以直接(LCA)求距离即可。
另外因为有重边(说好的只有单键呢),所以需要判重,一开始我用的(HASH)判重,结果又被卡了。。。
和(HASH)天理难容,每次用都被卡
最后一气之下(bitset)判重,总算是过了。
#include<cstdio>
#include<cmath>
#include<bitset>
using namespace std;
const int N = 1e4 + 10;
const int M = 1e5 + 10;
const int K = 15;
int fi[N], di[M], ne[M], cfi[N], cdi[M], cne[M], dfn[N], low[N], de[N], bl[N], f[N][K], l = 1, lc, ti, DCC, gn;
bool bg[M];
bitset<N>v[N];
inline int re()
{
int x = 0;
char c = getchar();
bool p = 0;
for (; c < '0' || c > '9'; c = getchar())
p |= c == '-';
for (; c >= '0' && c <= '9'; c = getchar())
x = x * 10 + c - '0';
return p ? -x : x;
}
inline void add(int x, int y)
{
di[++l] = y;
ne[l] = fi[x];
fi[x] = l;
}
inline void add_c(int x, int y)
{
cdi[++lc] = y;
cne[lc] = cfi[x];
cfi[x] = lc;
}
inline int minn(int x, int y)
{
return x < y ? x : y;
}
inline void sw(int &x, int &y)
{
int z = x;
x = y;
y = z;
}
void tarjan(int x, int la)
{
int i, y;
dfn[x] = low[x] = ++ti;
for (i = fi[x]; i; i = ne[i])
if (!dfn[y = di[i]])
{
tarjan(y, i);
low[x] = minn(low[x], low[y]);
if (low[y] > dfn[x])
bg[i] = bg[i ^ 1] = 1;
}
else
if (i ^ la ^ 1)
low[x] = minn(low[x], dfn[y]);
}
void dfs(int x)
{
int i, y;
bl[x] = DCC;
for (i = fi[x]; i; i = ne[i])
if (!bg[i] && !bl[y = di[i]])
dfs(y);
}
void dfs_2(int x)
{
int i, y;
for (i = 1; i <= gn; i++)
f[x][i] = f[f[x][i - 1]][i - 1];
for (i = cfi[x]; i; i = cne[i])
if ((y = cdi[i]) ^ f[x][0])
{
f[y][0] = x;
de[y] = de[x] + 1;
dfs_2(y);
}
}
int lca(int x, int y)
{
int i;
if (de[x] > de[y])
sw(x, y);
for (i = gn; ~i; i--)
if (de[f[y][i]] >= de[x])
y = f[y][i];
if (!(x ^ y))
return x;
for (i = gn; ~i; i--)
if (f[x][i] ^ f[y][i])
{
x = f[x][i];
y = f[y][i];
}
return f[x][0];
}
void pr(int x)
{
if (!x)
return;
pr(x >> 1);
printf("%d", x & 1);
}
int main()
{
int i, n, m, t, x, y;
n = re();
m = re();
gn = log2(n);
for (i = 1; i <= m; i++)
{
x = re();
y = re();
if (v[x][y] || v[y][x])
continue;
v[x][y] = v[y][x] = 1;
add(x, y);
add(y, x);
}
tarjan(1, 0);
for (i = 1; i <= n; i++)
if (!bl[i])
{
++DCC;
dfs(i);
}
for (i = 2; i <= l; i += 2)
{
x = bl[di[i ^ 1]];
y = bl[di[i]];
if (x ^ y)
{
add_c(x, y);
add_c(y, x);
}
}
de[1] = 1;
dfs_2(1);
t = re();
while (t--)
{
x = bl[re()];
y = bl[re()];
pr(de[x] + de[y] - (de[lca(x, y)] << 1) + 1);
printf("
");
}
return 0;
}