思路

并查集的好题

考虑到求满足条件限制的方案数,显然观察样例可知结果就是2^x,x是互不影响的边的集合数量

然后考虑如何求互不影响的边的集合数量

可以使用并查集,用i和i+n表示这个点的父亲连向它的边的两种指向,然后每次合并,u->lca,v->lca,如果lca不是u或v,合并u+n和v,v+n和u即可

为了保证复杂度,需要路径压缩一下

但是要注意这样的话,合并u+n和v,v+n和u必须在后面进行,不然会破坏树的结构

最后答案是\(2^{x}\),x是并查集个数/2

代码

  1. #include <cstdio>
  2. #include <algorithm>
  3. #include <cstring>
  4. using namespace std;
  5. int v[600400],fir[300400],nxt[600400],cnt;
  6. void addedge(int ui,int vi){
  7. ++cnt;
  8. v[cnt]=vi;
  9. nxt[cnt]=fir[ui];
  10. fir[ui]=cnt;
  11. }
  12. int jump[300400][20],dep[300400];
  13. void dfs(int u,int f){
  14. jump[u][0]=f;
  15. dep[u]=dep[f]+1;
  16. for(int i=1;i<20;i++)
  17. jump[u][i]=jump[jump[u][i-1]][i-1];
  18. for(int i=fir[u];i;i=nxt[i]){
  19. if(v[i]==f)
  20. continue;
  21. dfs(v[i],u);
  22. }
  23. }
  24. int lca(int x,int y){
  25. if(dep[x]<dep[y])
  26. swap(x,y);
  27. for(int i=19;i>=0;i--)
  28. if(dep[jump[x][i]]>=dep[y])
  29. x=jump[x][i];
  30. if(x==y)
  31. return x;
  32. for(int i=19;i>=0;i--)
  33. if(jump[x][i]!=jump[y][i])
  34. x=jump[x][i],y=jump[y][i];
  35. return jump[x][0];
  36. }
  37. const int MOD = 1000000007;
  38. int pow(int a,int b){
  39. int ans=1;
  40. while(b){
  41. if(b&1)
  42. ans=(1LL*ans*a)%MOD;
  43. a=(1LL*a*a)%MOD;
  44. b>>=1;
  45. }
  46. return ans;
  47. }
  48. int fa[600400],n,m;
  49. int find(int x){
  50. if(fa[x]==x)
  51. return x;
  52. else
  53. return fa[x]=find(fa[x]);
  54. }
  55. void merge(int x,int Lca){
  56. while(dep[jump[x][0]]>dep[Lca]){
  57. int f=jump[x][0];
  58. fa[find(x)]=find(f);
  59. fa[find(x+n)]=find(f+n);
  60. x=find(f);
  61. }
  62. }
  63. int ta[300300],tb[300300],Lca[300300];
  64. int main(){
  65. freopen("test.in","r",stdin);
  66. // freopen("test.out","w",stdout);
  67. scanf("%d %d",&n,&m);
  68. for(int i=1;i<=2*n;i++)
  69. fa[i]=i;
  70. for(int i=1;i<n;i++){
  71. int a,b;
  72. scanf("%d %d",&a,&b);
  73. addedge(a,b);
  74. addedge(b,a);
  75. }
  76. dfs(1,0);
  77. for(int i=1;i<=m;i++){
  78. scanf("%d %d",&ta[i],&tb[i]);
  79. Lca[i]=lca(ta[i],tb[i]);
  80. merge(ta[i],Lca[i]);
  81. merge(tb[i],Lca[i]);
  82. }
  83. for(int i=1;i<=m;i++){
  84. if(Lca[i]!=ta[i]&&Lca[i]!=tb[i]){
  85. fa[find(ta[i]+n)]=find(tb[i]);
  86. fa[find(tb[i]+n)]=find(ta[i]);
  87. }
  88. }
  89. int ans=0;
  90. for(int i=2;i<=n;i++){
  91. if(find(i)==find(i+n)){
  92. printf("0\n");
  93. return 0;
  94. }
  95. ans+=(find(i)==i);
  96. ans+=(find(i+n)==(i+n));
  97. }
  98. printf("%d\n",pow(2,ans/2));
  99. return 0;
  100. }

p4434 [COCI2017-2018#2] ​​Usmjeri的更多相关文章

  1. COCI2017/2018 CONTEST #7

    Prosjek 显然,越大的数应该越后参与平均数的计算,这样受较小数的影响就小一些 那我们就排个序,贪心的从最小的数开始往大的计算平均数即可 时间复杂度\(O(nlogn)\) Timovi 把分组分 ...

  2. Usmjeri(COCI2017.2)题解

    题意 给一棵N个节点的树,编号从1到N,再给定m对点(u,v),你要将树上的每条无向边变为有向边,使得给定的点对都满足u能到达v或v能到达u.问有多少种不同的方案,答案对(1e9+7)求余. 1 ≤ ...

  3. 2018. The Debut Album

    http://acm.timus.ru/problem.aspx?space=1&num=2018 真心爱过,怎么能彻底忘掉 题目大意: 长度为n的串,由1和2组成,连续的1不能超过a个,连续 ...

  4. Math.abs(~2018),掌握规律即可!

    Math.abs(~2018) 某前端群的入门问题长姿势了,一个简单的入门问题却引发了我的思考,深深的体会到自己在学习前端技术的同时忽略遗忘了一些计算机的基础知识. 对于 JS Math对象没什么可说 ...

  5. 肖秀荣8套卷2018pdf下载|2018肖秀荣冲刺8套卷pdf下载电子版

    肖秀荣8套卷2018pdf下载|2018肖秀荣冲刺8套卷pdf下载电子版 下载链接: https://u253469.ctfile.com/fs/253469-229815828

  6. 2018年的UX设计师薪酬预测,你能拿多少?

    以下内容由Mockplus团队翻译整理,仅供学习交流,Mockplus是更快更简单的原型设计工具.   一个经验丰富的设计师完全可以根据地区和专业来可以预期薪酬之间的差距,其中悬殊最高可达80K. 本 ...

  7. Hello 2018, Bye 2017

    2017年过去了,过去一年经历了太多,改变了好多好多,可以说人生进入了另一个阶段,有可能是成熟吧. 回顾2017 去年换了新工作,离开了将近工作了8年的公司,不带走一丝云彩,为其任劳任怨,最后没有任何 ...

  8. New Life With 2018

    2017年转眼过去了.对自己来说.这一大年是迷茫和认知的一年.我的第一篇博客就这样记录下自己的历程吧 一:选择 从进入这一行到现在已经一年多了,2016年11月份就像所有的应届毕业生一样,都贼反感毕业 ...

  9. 2017 年终总结 & 2018 年度计划

    不立几个 Flag,都不知道怎么作死 2017 年度计划完成情况: 1.健身时间不少于350天:  未完成 中断了22天,实际运动 343天   2.至少每个月看一本书:  及格 <切尔诺贝利的 ...

随机推荐

  1. 《你必须知道的495个C语言问题》读书笔记之第8-10章:字符串、布尔类型和预处理器

    一.字符和字符串 1. Q:为什么strcat(string, '!')不行? A:strcat()用于拼接字符串,所以应该写成strcat(string, "!")." ...

  2. lua数据类型的的操作(三)

    上一章我们学习了lua的数据类型,以及语法的定义,今天我们学习lua的数据类型操作,其实就是lua库一些api的操作,遇到对数据类型处理时,可以根据lua库提供的操作来实现. 一.字符串操作 1.字符 ...

  3. MVVM模式中ViewModel和View、Model有什么区别

    Model:很简单,就是业务逻辑相关的数据对象,通常从数据库映射而来,我们可以说是与数据库对应的model. View:也很简单,就是展现出来的用户界面. 基本上,绝大多数软件所做的工作无非就是从数据 ...

  4. SpringCloud 教程 | 终章

    错过了这一篇,你可能再也学不会 Spring Cloud 了!Spring Boot做为下一代 web 框架,Spring Cloud 作为最新最火的微服务的翘楚,你还有什么理由拒绝.赶快上船吧,老船 ...

  5. python学习-6 猜拳小游戏

    import random # 调用随机数模块 pc = random.randint(1,3) # 产生1-3的随机数 print("来玩个猜拳游戏吧!") a = '石头' b ...

  6. Linux/CentOS 配置Mysql-server过程和遇到错误解决方法

    第一步:下载mysql-server 方法1.wget url(你所要下载的链接,可以从mysq官网查找)到当前目录下 方法2.到mysql官网下载包之后通过xftp传到linux 第二步:解压tar ...

  7. k8s之调度器、预选策略及优选函数

    1.调度器(scheduler) 调度器的功能是调度Pod在哪个Node上运行,这些调度信息存储在master上的etcd里面,能够和etcd打交道的只有apiserver; kubelet运行在no ...

  8. 怎样获取响应头: Response Header

    1. 使用 xhr.getResponseHeader()可以获取指定响应头字段值. function getHeaderTime() { console.log(this.getResponseHe ...

  9. linux 安装redis 完整步骤

    最近在linux服务器上需要安装redis,来存放数据,增加用户访问数据的速度,由于是第一次安装,于是在百度上搜了一篇文章,按照这篇博客,顺利安装好了,因此将博主的文章拷过来记录一下,方便以后使用,也 ...

  10. CUDA中使用多维数组

    今天想起一个问题,看到的绝大多数CUDA代码都是使用的一维数组,是否可以在CUDA中使用一维数组,这是一个问题,想了各种问题,各种被77的错误状态码和段错误折磨,最后发现有一个cudaMallocMa ...