P7966 题解
首先每条边都要被选入一棵树中。
注意到如果令每条边的权值为两边的异或值,则对于每个
考虑求出图中的一个最大独立集作为根集,可以证明这个独立集的大小为
代码极短:
#include <bits/stdc++.h>
using namespace std;
#define MAXN 20
int n, ct; vector<int> e[MAXN]; int dis[MAXN], wfa[MAXN]; bool vis[65536]; vector<int> vec;
void dfs(int x, int f){for (auto i: e[x]) if (i ^ f) wfa[i] = 1<<(ct++), dis[i] = dis[x]^wfa[i], dfs(i, x);}
signed main(){
// freopen("constr.in", "r", stdin); freopen("constr.out", "w", stdout);
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> n; for (int i(1), u, v; i<=n; ++i) cin >> u >> v, e[u].push_back(v), e[v].push_back(u); dfs(0, -1); cout << (1<<(n-1)) << '\n';
for (int i(0); i<(1<<n); ++i) if (!vis[i]){vec.push_back(i); for (int j(0); j<n; ++j) vis[i^1<<j] = 1;}
for (auto i: vec){for (int j(0); j<=n; ++j) cout << (i^dis[j]) << ' '; cout << '\n';}
return 0;
}