ABC233

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;
}
View Code

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;
}
View Code

 

posted @ 2022-01-05 17:35  DeaL57  阅读(53)  评论(0编辑  收藏  举报