BZOJ 题目2152: 聪聪可可(树的点分治)
2015-10-08 10:04
447 查看
2152: 聪聪可可
Time Limit: 3 Sec Memory Limit: 259 MBSubmit: 1122 Solved: 585
[Submit][Status][Discuss]
Description
聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃、两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况下石头剪刀布就好了,可是他们已经玩儿腻了这种低智商的游戏。他们的爸爸快被他们的争吵烦死了,所以他发明了一个新游戏:由爸爸在纸上画n个“点”,并用n-1条“边”把这n个“点”恰好连通(其实这就是一棵树)。并且每条“边”上都有一个数。接下来由聪聪和可可分别随即选一个点(当然他们选点时是看不到这棵树的),如果两个点之间所有边上数的和加起来恰好是3的倍数,则判聪聪赢,否则可可赢。聪聪非常爱思考问题,在每次游戏后都会仔细研究这棵树,希望知道对于这张图自己的获胜概率是多少。现请你帮忙求出这个值以验证聪聪的答案是否正确。Input
输入的第1行包含1个正整数n。后面n-1行,每行3个整数x、y、w,表示x号点和y号点之间有一条边,上面的数是w。Output
以即约分数形式输出这个概率(即“a/b”的形式,其中a和b必须互质。如果概率为1,输出“1/1”)。Sample Input
51 2 1
1 3 2
1 4 1
2 5 3
Sample Output
13/25【样例说明】
13组点对分别是(1,1) (2,2) (2,3) (2,5) (3,2) (3,3) (3,4) (3,5) (4,3) (4,4) (5,2) (5,3) (5,5)。
【数据规模】
对于100%的数据,n<=20000。
HINT
Source
树的分治ac代码
/************************************************************** Problem: 2152 User: kxh1995 Language: C++ Result: Accepted Time:444 ms Memory:3464 kb ****************************************************************/ #include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #define max(a,b) (a>b?a:b) using namespace std; #define N 20100 int head ,cnt,pre ,sum,son ,vis ,deep[3],root,dis ; #define INF 0x3f3f3f3f int n,m,ans,k; struct s { int u,v,next,w; }edge[N<<1]; void add(int u,int v,int w) { edge[cnt].u=u; edge[cnt].v=v; edge[cnt].w=w; edge[cnt].next=head[u]; head[u]=cnt++; } int gcd(int a,int b) { if(a<b) { int t=a; a=b; b=t; } if(b==0) return a; return gcd(b,a%b); } void get_root(int u,int fa) { son[u]=1; pre[u]=0; int i; for(i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(v==fa||vis[v]) continue; get_root(v,u); son[u]+=son[v]; pre[u]=max(pre[u],son[v]); } pre[u]=max(pre[u],sum-son[u]); if(pre[u]<pre[root]) root=u; } void get_deep(int u,int fa) { deep[dis[u]]++; int i; for(i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(v==fa||vis[v]) continue; dis[v]=(dis[u]+edge[i].w)%3; get_deep(v,u); } } int get_sum(int x,int now) { dis[x]=now%3; deep[0]=deep[1]=deep[2]=0; get_deep(x,0); return deep[1]*deep[2]*2+deep[0]*deep[0]; } void work(int x) { ans+=get_sum(x,0); vis[x]=1; int i; for(i=head[x];i!=-1;i=edge[i].next) { int v=edge[i].v; if(vis[v]) continue; ans-=get_sum(v,edge[i].w); sum=son[v]; root=0; get_root(v,root); work(root); } } int main() { //int n,m; //while(scanf("%d",&n)!=EOF) //{ scanf("%d",&n); int i; cnt=0; memset(head,-1,sizeof(head)); for(i=1;i<n;i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); add(u,v,w); add(v,u,w); } sum=n; pre[0]=INF; memset(vis,0,sizeof(vis)); root=0; get_root(1,0); ans=0; //memset(deep,0,sizeof(deep)); work(root); int t=gcd(ans,n*n); printf("%d/%d\n",ans/t,(n*n)/t); // } }
相关文章推荐
- 使用Jsoup 抓取页面的数据
- Trigger a button click with JavaScript on the Enter key in a text box
- mysql使用手册
- 你是真的太累了么?
- leetcode 7&9 : Reverse Integer & Palindrome Number
- NoSQL学习二:MongoDB基本管理命令
- 查询结果字段别名(纯记录,防遗忘)
- iOS 获取文件大小
- windows 下的cmd 中远程登录oracle
- 游戏引擎架构 && windows 核心编程
- 为什么要搞vim
- CSS3 修改和去除移动端点击事件出现的背景框 (tap-highlight-color)
- Compare Version Numbers
- 没有广告的美女图片分享网站
- 哈希表
- JS实现常见的TAB、弹出层效果(TAB标签,斑马线,遮罩层等)
- 终结照片浏览器应用ios源码
- php if中存在赋值可能会存在的问题
- ieltsListen was compiled with optimization - stepping may behave oddly; variables may not be availab
- 802.11n 速率计算方法