[BZOJ2152]聪聪可可|树的点分治
来源:互联网 发布:属于nosql数据库的是 编辑:程序博客网 时间:2024/06/05 00:16
学了学点分治,主要思想就是找重心来防止树退化成链这样的东西,感觉写的不是很顺但是1A了。。找到一个部分的重心之后答案变成两部分,一是过重心的路径,二是不过重心的路径,二可以递归地得到,一的话可以对每个重心向下求出每个子节点的深度mod 3,然后记录下余0,1,2的数量,然后0和0组合,1和2组合,要注意排除来自同一颗子树的点对的重复计算,还要注意点对是有顺序的而且可以相同。。
#include<iostream>#include<cstdio>#include<memory.h>#define N 20005using namespace std;struct edge{ int e,q,next;}ed[N*2];int n,s,e,q,i,ne=0,ans=0,ms[N],rt[N],a[N],u[N],sum[3],sz[N],d[N];void add(int s,int e,int q){ ed[++ne].e=e;ed[ne].q=q; ed[ne].next=a[s];a[s]=ne;}int find(int x,int fa,int n){ sz[x]=1;ms[x]=0;rt[x]=20001; for (int j=a[x];j;j=ed[j].next) if (ed[j].e!=fa&&!u[ed[j].e]) { find(ed[j].e,x,n); sz[x]+=sz[ed[j].e];ms[x]=max(ms[x],sz[ed[j].e]); if (ms[rt[ed[j].e]]<ms[rt[x]]) rt[x]=rt[ed[j].e]; } ms[x]=max(ms[x],n-sz[x]); if (ms[x]<ms[rt[x]]) rt[x]=x; return rt[x];}void dfs(int x,int fa){ sum[d[x]]++;sz[x]=1; for (int j=a[x];j;j=ed[j].next) if (!u[ed[j].e]&&ed[j].e!=fa) { d[ed[j].e]=(d[x]+ed[j].q)%3; dfs(ed[j].e,x); sz[x]+=sz[ed[j].e]; }}void work(int now,int n){ int x=find(now,-1,n); u[x]=1; sum[0]=sum[1]=sum[2]=0; int s0,s1,s2; for (int j=a[x];j;j=ed[j].next) if (!u[ed[j].e]) { s0=sum[0];s1=sum[1];s2=sum[2]; d[ed[j].e]=ed[j].q%3;dfs(ed[j].e,x); ans+=(sum[0]-s0)*(s0+1)*2+(sum[1]-s1)*s2*2+(sum[2]-s2)*s1*2; } for (int j=a[x];j;j=ed[j].next) if (!u[ed[j].e]) work(ed[j].e,sz[ed[j].e]);}int gcd(int a,int b){return b==0? a:gcd(b,a%b);}int main(){ freopen("2152.in","r",stdin); scanf("%d",&n); memset(a,0,sizeof(a)); for (i=1;i<n;i++) { scanf("%d%d%d",&s,&e,&q); add(s,e,q);add(e,s,q); } memset(u,0,sizeof(u)); ms[20001]=10000000; work(1,n); int t=gcd(ans+n,n*n); printf("%d/%d\n",(ans+n)/t,n*n/t);}
0 0
- [BZOJ2152]聪聪可可|树的点分治
- 【BZOJ2152】聪聪可可-树的点分治
- BZOJ2152 聪聪可可(点分治)
- bzoj2152 聪聪可可【点分治】
- 【bzoj2152】【聪聪可可】【点分治】
- bzoj2152 聪聪可可 点分治
- 【bzoj2152】聪聪可可 点分治
- BZOJ2152 聪聪可可 点分治
- 【BZOJ2152】聪聪可可【点分治】
- [BZOJ2152]聪聪可可(点分治)
- bzoj2152: 聪聪可可(点分治)
- 【bzoj2152】聪聪可可 点分治
- [BZOJ2152]聪聪可可-点分治
- bzoj2152 聪聪与可可 点分治
- BZOJ2152[聪聪可可] 点分治
- BZOJ2152 聪聪可可 点分治题解
- bzoj2152: 聪聪可可(点分治)
- [BZOJ2152]聪聪可可(点分治)
- C中fgetc()和fputc简单用法介绍
- PHP文件上传、下载
- TCP/IP----路由协议(RIP、OSPF、BGP)
- sqoop入门实践
- lcc源代码解析之dag.c
- [BZOJ2152]聪聪可可|树的点分治
- js ==与===区别(两个等号与三个等号)
- 我的第一篇博客
- 2015年百度之星程序设计大赛 - 资格赛:1003 IP聚合
- struts2上传下载
- https单向/双向认证及tomcat配置https方法
- python socket(tcp/udp)编程
- Android 读取手机SD卡根目录下某个txt文件的文件内容
- vs2012编译ictclas