bzoj4455 & loj2091 [Zjoi2016] + Little Star inclusion and exclusion tree the DP (pressure like the DP +?)

Topic Portal

https://lydsy.com/JudgeOnline/problem.php?id=4455

https://loj.ac/problem/2091

answer

A very good question. (But in the examination room should be a sign it was

One is clearly wrong tree DP method:

So \ (dp [x] [i ] \) represents the tree \ (x \) to figure \ (i \) this point of time and then transferred directly to enumerate \ (x \) children and \ (i \ ) the child is matched.

Obviously there will be many such repeat the pairing (i.e., two points on the same point pairs FIG tree) is. Then I quickly put the algorithm to give up.

(Should think more of; get a lesson: think of a fake algorithm later to see if there is a way to change the algorithm to correct

Then a positive solution is very wonderful: Since we will repeat the pairing, then the figure will certainly have not been paired points. So what can be considered direct inclusion and exclusion of those points have not been paired, the point is the election of the ban.

The final inclusion and exclusion can get health care done right answer.

Time complexity \ (O (NN ^ 2 ^. 3) \) .


#include<bits/stdc++.h>

#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back

template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b, 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b, 1 : 0;}

typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii;

template<typename I> inline void read(I &x) {
    int f = 0, c;
    while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
    x = c & 15;
    while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
    f ? x = -x : 0;
}

const int N = 17 + 7;

int n, m, cnt;
ll ans;
int ban[N];
ll dp[N][N];
std::vector<int> g1[N], g2[N];

inline void dfs(int x, int fa = 0) {
    for (int i = 1; i <= n; ++i) dp[x][i] = !ban[i];
    int len = g2[x].size();
    for (int ii = 0, y; ii < len; ++ii) if (y = g2[x][ii], y != fa) {
        dfs(y, x);
        for (int i = 1; i <= n; ++i) if (!ban[i]) {
            int len = g1[i].size();
            ll sum = 0;
            for (int jj = 0, j; jj < len; ++jj) {
                j = g1[i][jj];
                sum += dp[y][j];
            }
            dp[x][i] = dp[x][i] * sum;
        }
    }
}

inline void calc() {
    dfs(1);
    ll sum = 0;
    for (int i = 1; i <= n; ++i) if (!ban[i]) sum += dp[1][i];
    if (cnt & 1) ans -= sum;
    else ans += sum;
}

inline void dfs1(int x) {
    if (x == n + 1) return calc();
    ban[x] = 0, dfs1(x + 1);
    ban[x] = 1, ++cnt, dfs1(x + 1), --cnt;
}

inline void work() {
    dfs1(1);
    printf("%lld\n", ans);
}

inline void init() {
    read(n), read(m);
    int x, y;
    for (int i = 1; i <= m; ++i) read(x), read(y), g1[x].pb(y), g1[y].pb(x);
    for (int i = 1; i < n; ++i) read(x), read(y), g2[x].pb(y), g2[y].pb(x);
}

int main() {
#ifdef hzhkk
    freopen("hkk.in", "r", stdin);
#endif
    init();
    work();
    fclose(stdin), fclose(stdout);
    return 0;
}

Guess you like

Origin www.cnblogs.com/hankeke/p/bzoj4455.html