ABCDE略
F
容易想到建图,我卡在如果把所有属于同一集合的边都加在图上,会让问题变复杂,当两个点属于同一集合的时候就不用在把这个边加上去了。
#include <bits/stdc++.h> #define ll long long #define ull unsigned long long #define rep(i,a,b) for(ll i=(a);i<=(b);i++) #define dec(i,a,b) for(ll i=(a);i>=(b);i--) #define pll pair<ll,ll> using namespace std; ll INF = 0x7f7f7f7f7f7f7f7f; const int N = 1e3 + 5; ll mod = 998244353; ll f[N], p[N]; vector<pll> g[N]; ll find(ll x) { return f[x] == x ? x : f[x] = find(f[x]); } bool add(ll x, ll y) { ll fx = find(x), fy = find(y); if (fx != fy) { f[fx] = fy; return 1; } return 0; } bool vis[N]; vector<ll> ans; bool match(ll u,ll v,ll fa) { if (p[u] == v) return 1; for (auto x : g[u]) { ll to = x.first; if (to != fa) { if (match(to, v, u)) { swap(p[to], p[u]); ans.push_back(x.second); return 1; } } } return 0; } void dfs(ll x) { vis[x] = 1; for (auto x : g[x]) { ll v = x.first; if (!vis[v]) dfs(v); } match(x, x, -1); } int main() { #ifdef _DEBUG freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout); #endif ios::sync_with_stdio(false); cin.tie(nullptr); ll n, m; cin >> n; rep(i, 1, n) { f[i] = i; cin >> p[i]; } cin >> m; bool fg = 1; rep(i, 1, m) { ll u, v; cin >> u >> v; if (add(u, v)) { g[u].push_back({ v,i }); g[v].push_back({ u,i }); } } rep(i, 1, n) { if (find(p[i]) != find(i) && p[i] != i) fg = 0; } if (!fg) cout << "-1\n"; else { rep(i, 1, n) { if (!vis[i]) dfs(i); } cout << ans.size() << '\n'; for (auto x : ans) { cout << x << ' '; } } return 0; }
G
分治一下
#include <bits/stdc++.h> #define ll long long #define ull unsigned long long #define rep(i,a,b) for(ll i=(a);i<=(b);i++) #define dec(i,a,b) for(ll i=(a);i>=(b);i--) #define pll pair<ll,ll> using namespace std; ll INF = 0x7f7f7f7f7f7f7f7f; const int N = 1e3 + 5; ll mod = 998244353; ll dp[55][55][55][55]; char g[55][55]; ll solve(ll lx, ll ly, ll rx, ll ry) { if (lx > rx) return 0; if (ly > ry) return 0; if (dp[lx][ly][rx][ry] < INF) return dp[lx][ly][rx][ry]; dp[lx][ly][rx][ry] = max(rx - lx + 1, ry - ly + 1); rep(i, lx, rx) { bool fg = 1; rep(j, ly, ry) { if (g[i][j] == '#') { fg = 0; break; } } if (fg) { dp[lx][ly][rx][ry] = min(dp[lx][ly][rx][ry], solve(lx, ly, i - 1, ry) + solve(i + 1, ly, rx, ry)); } } rep(i, ly, ry) { bool fg = 1; rep(j, lx, rx) { if (g[j][i] == '#') { fg = 0; break; } } if (fg) { dp[lx][ly][rx][ry] = min(dp[lx][ly][rx][ry], solve(lx, ly, rx, i - 1) + solve(lx, i + 1, rx, ry)); } } return dp[lx][ly][rx][ry]; } int main() { #ifdef _DEBUG freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout); #endif ios::sync_with_stdio(false); cin.tie(nullptr); ll n; cin >> n; rep(i, 1, n) { cin >> g[i]+1; } rep(i, 1, n) { rep(j, 1, n) { rep(k, 1, n) { rep(l, 1, n) { dp[i][j][k][l] = INF; } } } } cout << solve(1, 1, n, n) << '\n'; return 0; }