【汕头市选2014】分叉 jzoj 3630 dfs
2018-01-31 12:30
239 查看
题目
给出一棵N 个点的树,点的编号是1, 2,。。。,N。对于3 个点{a,b,c},如果不存在一条简单路径同时经过a,b,c,那么{a,b,c}是一个分叉。
统计不同分叉的数量。
分析
比赛时爆int.开了long long就对了
我们可以很方便的找到有一条简单路径经过{x,y,z}三元组的个数
然后拿所有的三元组个数去减就好了.
code
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<string> #include<algorithm> #define maxn 200005 #define maxm 300005 #define INF 0x7fffffff; using namespace std; struct arr{ int x,y; int next; }edge[maxm]; int ls[maxn]; int edge_m; long long son[maxn]; long long f[maxn]; long long n; void add(int x,int y) { edge[++edge_m]=(arr){x,y,ls[x]},ls[x]=edge_m; edge[++edge_m]=(arr){y,x,ls[y]},ls[y]=edge_m; } int dfs(int x,int r) { son[x]=1; for (int i=ls[x];i;i=edge[i].next) { if (edge[i].y==r) continue; dfs(edge[i].y,x); son[x]+=son[edge[i].y]; } int num=1; for (int i=ls[x];i;i=edge[i].next) { if (edge[i].y==r) continue; num+=son[edge[i].y]; f[x]+=son[edge[i].y]*(n-num); } } int main() { freopen("fork.in","r",stdin); freopen("fork.out","w",stdout); scanf("%d",&n); for (int i=1;i<n;i++) { int x,y; scanf("%d%d",&x,&y); add(x,y); } dfs(1,0); long long ans=(long long)(n*(n-1)*(n-2)/6); for (int i=1;i<=n;i++) { ans-=f[i]; } cout<<ans; }
相关文章推荐
- jzoj3630 【汕头市选2014】分叉(树上统计)
- 【jzoj3630】【汕头市选2014】【分叉】【树形动态规划】
- JZOJ3630. 【汕头市选2014】分叉(fork)
- jzoj P1842【汕头市选2014】平均
- 【jzoj3632】【汕头市选2014】【舞伴】【状态压缩动态规划】
- jzoj P1843【汕头市选2014】小球
- jzoj 3631 【汕头市选2014】三角(triangle)
- jzoj P1845【汕头市选2014】约数
- JZOJ3632【汕头市选2014】舞伴(perm)
- 【汕头市选2014】分叉(fork)
- JZOJ 1842——【汕头市选2014】平均
- 【汕头市选2014】分叉(fork)
- JZOJ 3631. 【汕头市选2014】三角(triangle)
- 【汕头市选2014】舞伴 jzoj 3632 状压dp
- JZOJ 3632. 【汕头市选2014】舞伴
- 【JZOJ3633】【汕头市选2014】数数(count) (栈)
- 【省选专题二】字符串 jzoj 3756【NOI2014】动物园
- 【汕头市选2014】数数
- JZOJ 3782. 【NOIP2014模拟8.17】组队