P2783 有机化学之神偶尔会作弊

· · 算法·理论

水黑题怎么变成紫题后还这么水(

怎么变蓝了(

学完了Tarjan之后,想多练几道题,看到模板题怎么都是绿题,突然发现这有个紫题怎么看都像是无向图边双连通分量Tarjan缩点模板,于是心血来潮

怎么大家都在用LCA啊我不会啊(

但这道题数据水到缩完点直接搜索就能过

#include <iostream>
#include <vector>
#include <stack>
#include <cstring>
#define MAXN 10001
using namespace std;

int n, m, dfn[MAXN], low[MAXN], coli, col[MAXN], cnt, d[MAXN];
bool vis[MAXN];
stack <int> st;
vector <int> g[MAXN], ng[MAXN];

void Tarjan(int u, int lst)
{
    dfn[u] = low[u] = ++cnt;
    vis[u] = true;
    st.push(u);
    for(int x = 0; x < g[u].size(); x++)
    {
        int v = g[u][x];
        if(v == lst) continue; //只需要加这一行就变成了无向图缩点
        if(!dfn[v])
        {
            Tarjan(v, u);
            low[u] = min(low[u], low[v]);
        }
        else if(vis[v]) low[u] = min(low[u], dfn[v]);
    }
    if(dfn[u] == low[u])
    {
        coli++;
        int v;
        do
        {
            v = st.top(); st.pop();
            vis[v] = false;
            col[v] = coli;
        } while(v != u);
    }
}

void er(int i)
{
    vector <int> ans;
    while(i)
    {
        ans.push_back(i % 2);
        i >>= 1;
    }
    for(int x = ans.size()-1; x >= 0; x--) cout << ans[x];
    cout << endl;
}

void dfs(int u)
{
    for(int x = 0; x < ng[u].size(); x++)
    {
        int v = ng[u][x];
        if(!d[v])
        {
            d[v] = d[u] + 1;
            dfs(v);
        }
    }
}

int findAns(int i, int j)
{
    memset(d, 0, sizeof(d));
    d[i] = 1;
    dfs(i);
    return d[j];
}

int main()
{
    int tot;
    cin >> n >> m;
    for(int x = 0; x < m; x++)
    {
        int u, v;
        cin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    for(int x = 1; x <= n; x++)
        if(!dfn[x]) Tarjan(x, 0);
    for(int x = 1; x <= n; x++)
    {
        for(int y = 0; y < g[x].size(); y++)
        {
            int v = g[x][y];
            if(col[x] != col[v])
            {
                ng[col[x]].push_back(col[v]);
                ng[col[v]].push_back(col[x]);
            }
        }
    }
    cin >> tot;
    while(tot--)
    {
        int u, v;
        cin >> u >> v;
        er(findAns(col[u], col[v]));
    }
    return 0;
}