[代码]SGU 270 Thimbles
Abstract
SGU 270 Thimbles
图论 技巧 打补丁
Body
非常tricky的problem,有幸1y。
简单来说就是考虑每个点和点1直接联通,间接联通,在不在环里的情况。然后点1自己还要特判。
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; int N, M; bool vis[111]; int g[111][111]; bool dfs(int s, int t) { vis[s] = 1; if (s == t) return 1; for (int u = 0; u < N; ++u) { if (!g[s][u] || vis[u]) continue; if (dfs(u, t)) return 1; } return 0; } bool cyc(int u) { bool res; for (int v = 0; v < N; ++v) { if (!g[u][v]) continue; g[u][v]--; g[v][u]--; memset(vis, 0, sizeof(vis)); res = dfs(u, v); g[u][v]++; g[v][u]++; if (res) return 1; } return 0; } bool hmr(int u) { memset(vis, 0, sizeof(vis)); if (!dfs(0, u)) return 0; int x = g[0][u]; g[0][u] = g[u][0] = 0; memset(vis, 0, sizeof(vis)); if (x&1 || dfs(0, u)) { g[0][u] = g[u][0] = x; return 1; } bool res = cyc(0)||cyc(u); g[0][u] = g[u][0] = x; return res; } int main() { int i, j, k, u, v; cin >> N >> M; while (M--) { cin >> u >> v; u--; v--; g[u][v]++; g[v][u]++; } bool mdk = 1; for (u = 1; u<N && mdk; ++u) if (g[0][u]) mdk = 0; int syk = 0; for (u = 1; u<N && !mdk; ++u) { if (!g[0][u]) continue; int x = g[0][u]; if ((x&1)==0) { mdk = 1; break; } g[0][u] = g[u][0] = 0; memset(vis, 0, sizeof(vis)); if (dfs(0, u)) { g[0][u] = g[u][0] = x; mdk = 1; break; } if (x>1 && cyc(u)) mdk = 1; g[0][u] = g[u][0] = x; if (x>1) syk++; } mdk |= (syk>=2); if (mdk) cout<<"1 "; for (u = 1; u < N; ++u) if (hmr(u)) printf("%d ", u+1); cout << endl; return 0; }