HDU 3926 (图同构)

题目链接:点击这里

题意:给出两个最大度数是2的无向图, 判断是否同构.

因为最大度数是2, 直接把所有的环和链抓出来分别判断相等就好了.

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <vector>
#include <cstring>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define maxn 111111
#define maxm 411111

struct E {
    int v, next;
}edge1[maxm], edge2[maxm];
int head1[maxn], head2[maxn];
vector <int> ans1[2], ans2[2];
int cnt1, cnt2;
int n1, n2, m1, m2;
bool vis[maxn], is_loop;
int len;

void add_edge (int u, int v, int op) {
    if (op == 1) {
        edge1[cnt1].v = v, edge1[cnt1].next = head1[u], head1[u] = cnt1++;
    }
    else {
        edge2[cnt2].v = v, edge2[cnt2].next = head2[u], head2[u] = cnt2++;
    }
}

void dfs1 (int u, int fa) { 
    vis[u] = 1;
    len++;
    for (int i = head1[u]; i != -1; i = edge1[i].next) {
        int v = edge1[i].v;
        if (v == fa) continue;
        if (vis[v]) {
            is_loop = 1;
            continue;
        }
        dfs1 (v, u);
    }
}

void dfs2 (int u, int fa) {
    vis[u] = 1;
    len++;
    for (int i = head2[u]; i != -1; i = edge2[i].next) {
        int v = edge2[i].v;
        if (v == fa) continue;
        if (vis[v]) {
            is_loop = 1;
            continue;
        }
        dfs2 (v, u);
    }
}

bool ok () {
    sort (ans1[0].begin (), ans1[0].end ()); sort (ans1[1].begin (), ans1[1].end ());
    sort (ans2[0].begin (), ans2[0].end ()); sort (ans2[1].begin (), ans2[1].end ());
    if (ans1[0].size () != ans2[0].size () || ans1[1].size () != ans2[1].size ())
        return 0;
    int Max = ans1[0].size ();
    for (int i = 0; i < Max; i++) if (ans1[0][i] != ans2[0][i]) return 0;
    Max = ans1[1].size ();
    for (int i = 0; i < Max; i++) if (ans1[1][i] != ans2[1][i]) return 0;
    return 1;
}

int main () {
    int t, kase = 0;
    scanf ("%d", &t);
    while (t--) {
        scanf ("%d%d", &n1, &m1);
        memset (head1, -1, sizeof head1);
        memset (head2, -1, sizeof head2);
        cnt1 = 0;
        for (int i = 0; i < m1; i++) {
            int u, v;
            scanf ("%d%d", &u, &v);
            add_edge (u, v, 1);
            add_edge (v, u, 1);
        }

        scanf ("%d%d", &n2, &m2);
        cnt2 = 0;
        for (int i = 0; i < m2; i++) {
            int u, v;
            scanf ("%d%d", &u, &v);
            add_edge (u, v, 2);
            add_edge (v, u, 2);
        }

        printf ("Case #%d: ", ++kase);
        if (n1 != n2 || m1 != m2) {
            printf ("NO\n");
            continue;
        }
        ans1[0].clear (), ans1[1].clear (),  ans2[0].clear (), ans2[1].clear ();
        memset (vis, 0, sizeof vis);
        for (int i = 1; i <= n1; i++) if (!vis[i]) {
            len = 0;
            is_loop = 0;
            dfs1 (i, 0); 
            if (is_loop) {
                ans1[1].push_back (len);
            }
            else
                ans1[0].push_back (len);
        }
        memset (vis, 0, sizeof vis);
        for (int i = 1; i <= n1; i++) if (!vis[i]) {
            len = 0;
            is_loop = 0;
            dfs2 (i, 0);
            if (is_loop) {
                ans2[1].push_back (len);
            }
            else
                ans2[0].push_back (len);
        }
        printf ("%s\n", ok () ? "YES" : "NO");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值