Hướng dẫn giải của VM 14 Bài 18 - Cây khung
Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Lưu ý: Các code mẫu dưới đây chỉ mang tính tham khảo và có thể không AC được bài tập này
Code mẫu của ladpro98
#include <bits/stdc++.h> #define ii pair<int, int> #define X first #define Y second const int N = 2000; using namespace std; struct disjoint_set { int P[N]; disjoint_set() {for(int i = 0; i < N; i++) P[i] = i;} int at(int x) {return (x == P[x]) ? P[x] : (P[x] = at(P[x]));} void join(int x, int y) {P[at(x)] = at(y);} } DS; int id[N][N]; vector<int> a[N]; int T[N]; bool inST[N], was[N], con[N][N]; ii e[N]; int n, m; void DFS(int u) { was[u] = true; int i, v; for(i = 0; i < a[u].size(); i++) { v = a[u][i]; if (!was[v] && con[u][v]) { T[v] = u; DFS(v); } } } void PRINT() { for(int i = 1; i <= m; i++) if (inST[i]) printf("%d %d\n", e[i].X, e[i].Y); } int main() { scanf("%d %d", &n, &m); int i, x, y; for(i = 1; i <= m; i++) { scanf("%d %d", &e[i].X, &e[i].Y); a[e[i].X].push_back(e[i].Y); a[e[i].Y].push_back(e[i].X); id[e[i].X][e[i].Y] = id[e[i].Y][e[i].X] = i; } int cnt = 0; for(i = 1; i <= m; i++) { x = DS.at(e[i].X); y = DS.at(e[i].Y); if (x != y) { con[e[i].X][e[i].Y] = con[e[i].Y][e[i].X] = true; inST[i] = true; DS.join(x, y); cnt++; } if (cnt == n - 1) break; } printf("3\n"); PRINT(); for(i = 1; i <= m; i++) if (!inST[i]) { inST[i] = true; con[e[i].X][e[i].Y] = con[e[i].Y][e[i].X] = false; int s = e[i].X, t = e[i].Y; DFS(s); inST[id[T[t]][t]] = false; PRINT(); inST[id[T[t]][t]] = true; inST[id[T[T[t]]][T[t]]] = false; PRINT(); break; } return 0; }
Code mẫu của RR
#include <iostream> #include <algorithm> #include <vector> #include <cstring> using namespace std; vector<int> ke[1011]; int n, m, cnt; int father[1011], getIn[1011], getOut[1011]; bool visited[1011], hasSolution = false; int lab[1011]; int getRoot(int u) { if (lab[u] < 0) return u; else return lab[u] = getRoot(lab[u]); } void merge(int u, int v) { u = getRoot(u); v = getRoot(v); lab[u] += lab[v]; lab[v] = u; } vector<int> cycle; bool inCycle[1011]; void find(int x) { memset(lab, -1, sizeof lab); for(int i = 0; i < cycle.size(); ++i) if (i != x) { int j = (i + 1) % cycle.size(); int u = cycle[i], v = cycle[j]; if (getRoot(u) != getRoot(v)) { cout << u << ' ' << v << endl; merge(u, v); } } for(int u = 1; u <= n; ++u) { for(int i = 0; i < ke[u].size(); ++i) { int v = ke[u][i]; if (getRoot(u) != getRoot(v)) { cout << u << ' ' << v << endl; merge(u, v); } } } } void dfs(int u) { getIn[u] = ++cnt; visited[u] = true; for(int i = 0; i < ke[u].size(); ++i) { int v = ke[u][i]; if (v == father[u]) continue; if (!visited[v]) { father[v] = u; dfs(v); } else { if (!getOut[v]) { cycle.push_back(v); inCycle[v] = true; int x = u; while (!inCycle[x]) { cycle.push_back(x); inCycle[x] = true; x = father[x]; } if (!hasSolution) { hasSolution = true; cout << 3 << endl; find(0); find(1); find(2); } } } } getOut[u] = ++cnt; } int main() { cin >> n >> m; for(int i = 0; i < m; ++i) { int u, v; cin >> u >> v; ke[u].push_back(v); ke[v].push_back(u); } dfs(1); }
Code mẫu của skyvn97
#include<cstdio> #include<queue> #include<vector> #define MAX 2222 #define FOR(i,a,b) for (int i=(a);i<=(b);i=i+1) #define REP(i,n) for (int i=0;i<(n);i=i+1) #define FORE(i,v) for (__typeof((v).begin()) i=(v).begin();i!=(v).end();i++) #define fi first #define se second using namespace std; typedef pair<int,int> ii; inline int nextInt(void) { int x; scanf("%d",&x); return (x); } class DSU { private: vector<int> up; int find(int x) { if (up[x]<0) return (x); up[x]=find(up[x]); return (up[x]); } public: DSU() {} DSU(int n) { up.assign(n+7,-1); } bool join(int a,int b) { int x=find(a); int y=find(b); if (x==y) return (false); up[y]=x; return (true); } }; ii edge[MAX]; vector<int> g[MAX]; vector<int> cyc; int n,m; bool vst[MAX]; int p[MAX]; void loadgraph(void) { n=nextInt(); m=nextInt(); FOR(i,1,m) { int u=nextInt(); int v=nextInt(); edge[i]=ii(u,v); g[u].push_back(i); g[v].push_back(i); } } void bfs(int s,int f,int blk) { queue<int> q; vst[s]=true; q.push(s); while (!q.empty()) { int u=q.front();q.pop(); if (u==f) return; FORE(it,g[u]) if (*it!=blk) { int v=edge[*it].fi^edge[*it].se^u; if (!vst[v]) { vst[v]=true; p[v]=*it; q.push(v); } } } } void trace(int s,int t) { while (t!=s) { cyc.push_back(p[t]); t=edge[p[t]].fi^edge[p[t]].se^t; } } void findcycle(void) { DSU dsu=DSU(n); FOR(i,1,m) if (!dsu.join(edge[i].fi,edge[i].se)) { int u=edge[i].fi; int v=edge[i].se; bfs(u,v,i); trace(u,v); cyc.push_back(i); return; } } void findtree(int id) { DSU dsu=DSU(n); REP(i,cyc.size()) if (i!=id) { int u=edge[cyc[i]].fi; int v=edge[cyc[i]].se; printf("%d %d\n",u,v); dsu.join(u,v); } FOR(i,1,m) { int u=edge[i].fi; int v=edge[i].se; if (dsu.join(u,v)) printf("%d %d\n",u,v); } } void process(void) { printf("3\n"); REP(i,3) findtree(i); } int main(void) { loadgraph(); findcycle(); process(); return 0; }
Bình luận