NC14248 Treepath
题目地址:
基本思路:
很简单的一个树染色,感觉非常像上场div2 D的一部分,昨天刚补了那题,所以一下就想到了;
我们直接将图黑白染色,我们可以知道黑白染色之后,同种颜色之间的路径一定就是偶数的,所以我们把每种颜色的数量统计一下,假如黑色颜色节点有n个那么算下两两组合,就能组合出(n-1)!种路径,白色颜色节点同理,两者相加就是答案。
参考代码:
#pragma GCC optimize(2) #pragma GCC optimize(3) #include <bits/stdc++.h> using namespace std; #define IO std::ios::sync_with_stdio(false) #define int long long #define rep(i, l, r) for (int i = l; i <= r; i++) #define per(i, l, r) for (int i = l; i >= r; i--) #define mset(s, _) memset(s, _, sizeof(s)) #define pb push_back #define pii pair <int, int> #define pdd pair <double, double> #define mp(a, b) make_pair(a, b) #define INF 1e18 const int maxn = 1e5 + 10; struct Edge{ int to,next; }edge[maxn << 1]; int n,cnt,head[maxn]; void add_edge(int u,int v){ edge[++cnt].next = head[u]; edge[cnt].to = v; head[u] = cnt; } int color[maxn]; void dfs(int u,int p,int f) {//黑白染色; color[u] = f; for (int i = head[u]; i != -1; i = edge[i].next) { int to = edge[i].to; if (to == p) continue; dfs(to, u, 3 - f); } } int fac[maxn]; signed main() { IO; cnt = 0; mset(head,-1); cin >> n; rep(i,1,n) fac[i] = fac[i-1] + i;//预处理阶乘; rep(i,1,n-1){ int u,v; cin >> u >> v; add_edge(u,v); add_edge(v,u); } dfs(1,0,1); int f1 = 0 ,f2 = 0;//记录两种颜色的数目; rep(i,1,n){ if(color[i] == 1) f1++; else if(color[i] == 2) f2++; } int ans = fac[f1 - 1] + fac[f2 - 1];//两两连成一条路径; cout << ans << '\n'; return 0; }