您的位置:首页 > 其它

[BZOJ2152]聪聪可可

2015-07-18 23:40 246 查看
原题地址

点分治.

AC code:

#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int N=20010;
const int INF=1<<28;
int  n,a,m,mins,root;
int  son
;
int  f
[3];
bool del
;

struct Data{
int v,w;

Data(int v,int w):v(v),w(w) {}
};
vector<Data> G
;

void read(){
scanf("%d",&n);
a=n;
for(int i=1;i<n;i++){
int x,y,w;
scanf("%d%d%d",&x,&y,&w);
G[x].push_back(Data(y,w));
G[y].push_back(Data(x,w));
}
}

void DFS1(int pre,int p){
int maxs=-INF;
son[p]=1;
for(int i=0;i<G[p].size();i++){
Data q=G[p][i];
if(q.v==pre||del[q.v]) continue;
DFS1(p,q.v);
son[p]+=son[q.v];
maxs=max(maxs,son[q.v]);
}
maxs=max(maxs,m-son[p]);
if(maxs<mins){
root=p;
mins=maxs;
}
}

void DFS2(int anc,int pre,int p,int w){
son[p]=1;
f[anc][w%3]++;
for(int i=0;i<G[p].size();i++){
Data q=G[p][i];
if(q.v==pre||del[q.v]) continue;
DFS2(anc,p,q.v,(w+q.w)%3);
son[p]+=son[q.v];
}
}

void work(int p,int tot){
int r;
int sum[3]={0};

m=tot;mins=INF;
DFS1(0,p);
r=root;
for(int i=0;i<G[r].size();i++){
Data q=G[r][i];
if(del[q.v]) continue;
f[q.v][0]=f[q.v][1]=f[q.v][2]=0;
DFS2(q.v,r,q.v,q.w%3);
for(int i=0;i<=2;i++) sum[i]+=f[q.v][i];
}
for(int i=0;i<G[r].size();i++){
Data q=G[r][i];
if(del[q.v]) continue;
a+=f[q.v][0]*(sum[0]-f[q.v][0]);
a+=f[q.v][1]*(sum[2]-f[q.v][2]);
a+=f[q.v][2]*(sum[1]-f[q.v][1]);
a+=(f[q.v][0]<<1);
}
del[r]=1;
for(int i=0;i<G[r].size();i++){
Data q=G[r][i];
if(del[q.v]) continue;
work(q.v,son[q.v]);
}
}

int gcd(int x,int y){
return y?gcd(y,x%y):x;
}

int main(){
read();
work(1,n);
int g=gcd(a,n*n);
printf("%d/%d",a/g,n*n/g);

return 0;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: