QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#622215#5307. Subgraph IsomorphismPonyHexML 0ms0kbC++203.3kb2024-10-08 20:19:132024-10-08 20:19:14

Judging History

你现在查看的是最新测评结果

  • [2024-10-08 20:19:14]
  • 评测
  • 测评结果:ML
  • 用时:0ms
  • 内存:0kb
  • [2024-10-08 20:19:13]
  • 提交

answer

#define _CRT_SECURE_NO_WARNINGS 1
#include<bits/stdc++.h>
#include<unordered_map>
#include<unordered_set>
using namespace std;
#define double long double
//#define int long long
#define lc u<<1
#define rc u<<1|1
#define endl "\n"
#define X first
#define Y second
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> PII;
const ll N = 2e6 + 5;
const ll maxm = 2e18;
const ll mod = 1e9 + 7;

ll exgcd(ll a, ll b, ll& x, ll& y);

ll n, m;
vector<vector<ll> >e(N);
int dfn[N] = { 0 }, low[N] = { 0 }, tot = 0;//时间戳和回溯时间戳
int stk[N] = { 0 }, instk[N] = { 0 }, top = 0;
int scc[N] = { 0 }, siz[N] = { 0 }, cnt = 0;

const ll mask = 19260817;
ull shift(ull x) {
    x ^= mask; x ^= x << 13;
    x ^= x >> 7; x ^= x << 17;
    x ^= mask; return x;
}

ull gethash(int cur, int pr) {
    ull curhash = 1;
    for (auto p = e[cur].begin(); p != e[cur].end(); p++) {
        ll v = *p;
        if (v == pr)continue;
        //if (scc[v]==scc[cur])continue;
        curhash += shift(gethash(v, cur));
    }
    return curhash;
}


void tarjan(ll x, ll pre) {
    dfn[x] = low[x] = ++tot;
    stk[++top] = x; instk[x] = 1;
    for (auto p = e[x].begin(); p != e[x].end(); p++) {
        ll y = *p;
        if (y == pre)continue;
        if (!dfn[y]) {
            tarjan(y, x);
            low[x] = min(low[x], low[y]);
        }
        else if (dfn[y] && instk[y]) {
            low[x] = min(low[x], dfn[y]);
        }
    }
    if (low[x] == dfn[x]) {
        ++cnt;
        int y = 1;
        do {
            y = stk[top--];
            instk[y] = 0;
            scc[y] = cnt;
            siz[cnt]++;
        } while (y != x);
    }
}

void solve() {
    cin >> n >> m; for (int i = 1; i <= n; i++)e[i].clear();
    for (int i = 1; i <= m; i++) {
        ll u, v; cin >> u >> v;
        e[u].push_back(v); e[v].push_back(u);
    }
    if (m < n) {
        cout << "YES" << endl; return;
    }
    if (m > n) {
        cout << "NO" << endl; return;
    }

    //然后对成环的节点跑树哈希
    //缩点,我不会放弃缩点
    tot = 0; top = 0; cnt = 0;
    for (int i = 1; i <= n; i++) {
        dfn[i] = 0, low[i] = 0;
        stk[i] = 0, instk[i] = 0;
        scc[i] = 0, siz[i] = 0;
    }

    for (int i = 1; i <= n; i++) {
        if (dfn[i] == 0)
            tarjan(i, 0);
    }

    ull ans = 0;
    for (int i = 1; i <= n; i++) {
        if (siz[scc[i]] > 1) {
            if (ans == 0) {
                ans = gethash(i, 0);
            }
            else {
                if (ans != gethash(i, 0)) {
                    cout << "NO" << endl; return;
                }
            }
        }
    }
    cout << "YES" << endl;
    return;
}

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    ll t = 1;cin >> t;
    while (t--)solve();
    return 0;
}

ll exgcd(ll a, ll b, ll& x, ll& y) {
    if (b == 0) {
        x = 1; y = 0;
        return a;
    }
    ll g = exgcd(b, a % b, x, y);
    ll temp = x;
    x = y;
    y = temp - (a / b) * y;
    return g;
}

/*
ll ksm(ll a, ll b) {
    ll base = a;
    ll ans = 1;
    while (b) {
        if (b & 1)ans *= base;
        base *= base;
        b >>= 1;
    }
    return ans;
}*/
/*
ll gcd(ll a, ll b) {
    return b ? gcd(b, a % b) : a;
}*/

详细

Test #1:

score: 0
Memory Limit Exceeded

input:

4
7 6
1 2
2 3
3 4
4 5
5 6
3 7
3 3
1 2
2 3
3 1
5 5
1 2
2 3
3 4
4 1
1 5
1 0

output:


result: