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;
}
京公网安备 11010502036488号