题意就是判断两个图是否同构,标准的判断图的同构是很难的,不过这个题却是例外。
每个kid都只有两只手,也就是说每个点的度最大为2,这个是解题的关键!每个点的度最大为2,也就是说图上只存在三种形态:独立的点,链跟环。
这样问题就简单了,分别找出两个图中的点,链跟环,分别比较时否完全相同即可。
#include<algorithm> #include<iostream> #include<cstring> #include<fstream> #include<sstream> #include<vector> #include<string> #include<cstdio> #include<bitset> #include<queue> #include<stack> #include<cmath> #include<map> #include<set> #define FF(i, a, b) for(int i=a; i<b; i++) #define FD(i, a, b) for(int i=a; i>=b; i--) #define REP(i, n) for(int i=0; i<n; i++) #define CLR(a, b) memset(a, b, sizeof(a)) #define debug puts("**debug**") #define LL long long #define PB push_back #define MP make_pair #define eps 1e-10 using namespace std; const int maxn = 10010; int n, m, u, v, dfs_clock; vector<int> G[maxn], t1, t2; bool vis[maxn]; int in[maxn]; void dfs(int u) { vis[u] = 1; dfs_clock++; REP(i, G[u].size()) { int v = G[u][i]; if(!vis[v]) dfs(v); } } int main() { int T; scanf("%d", &T); FF(kase, 1, T+1) { t1.clear(); t2.clear(); scanf("%d%d", &n, &m); REP(i, n) G[i].clear(); CLR(in, 0); while(m--) { scanf("%d%d", &u, &v); u--; v--; G[u].PB(v); G[v].PB(u); in[u]++, in[v]++; } CLR(vis, 0); //先找独立的点 或者链 REP(i, n) if(in[i] < 2 && !vis[i]) { vis[i] = 1; dfs_clock = 0; dfs(i); t1.PB(dfs_clock); } //剩下的就都是环了 REP(i, n) if(!vis[i]) { vis[i] = 1; dfs_clock = 0; dfs(i); t1.PB(dfs_clock + 10000); } scanf("%d%d", &n, &m); REP(i, n) G[i].clear(); CLR(in, 0); while(m--) { scanf("%d%d", &u, &v); u--; v--; G[u].PB(v); G[v].PB(u); in[u]++, in[v]++; } CLR(vis, 0); REP(i, n) if(in[i] < 2 && !vis[i]) { vis[i] = 1; dfs_clock = 0; dfs(i); t2.PB(dfs_clock); } REP(i, n) if(!vis[i]) { vis[i] = 1; dfs_clock = 0; dfs(i); t2.PB(dfs_clock + 10000); } sort(t1.begin(), t1.end()); sort(t2.begin(), t2.end()); int a = t1.size(), b = t2.size(); bool flag = 0; if(a != b) flag = 1; REP(i, a) if(t1[i] != t2[i]) { flag = 1; break; } printf("Case #%d: %s\n", kase, flag ? "NO" : "YES"); } return 0; }