题意:

有一个n个点,m条边的图,没有重边、自环,且每一条边最多属于一个环路。

给出q组询问,每次询问u,v两点间的路径有多少种可能。

思路:

先看下方样例说明:

由样例说明可以得知,路径上每经过一个环,路径种数就会乘2,而且最终答案一定是2^n;

因此使用tarjan算法求出图中的环,由于题目限制,求点双联通分量和边双联通分量效果相同。因边双联通分量好写,懒惰的作者采用了它 -~_~-

代码:

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<cstdlib>
  5. #include<algorithm>
  6. #include<queue>
  7. #include<stack>
  8. #include<vector>
  9. #define ll long long
  10. #define MOD 1000000007
  11. using namespace std;
  12. vector<int>a[],b[];
  13. stack<int>s;
  14. int n,m,q,mm=,dep[],dfn[],low[],fa[],p[][],color[],times,cnt;
  15. bool vis[],viss[];
  16. void tarjan(int u){
  17. int i,j,child=,v;
  18. s.push(u);vis[u]=;
  19. dfn[u]=low[u]=times++;
  20. for(i=;i<a[u].size();i++){
  21. v=a[u][i];
  22. if(!vis[v]){
  23. child++;fa[v]=u;
  24. tarjan(v);
  25. low[u]=min(low[u],low[v]);
  26. }
  27. else if(v!=fa[u]) low[u]=min(low[u],dfn[v]);
  28. }
  29. if(dfn[u]==low[u]){
  30. cnt++;
  31. int count=,tmp;
  32. while(!s.empty()){
  33. tmp=s.top();
  34. color[tmp]=cnt+n;
  35. s.pop();count++;
  36. if(tmp==u) break;
  37. }
  38. if(count==) color[tmp]=tmp;
  39. }
  40. }
  41. void dfs(int u){
  42. int i,v,t1,t2;t1=color[u];
  43. viss[t1]=;vis[u]=;
  44. for(i=;i<a[u].size();i++){
  45. v=a[u][i];
  46. t2=color[v];
  47. if(viss[t2]) goto skip;
  48. mm++;p[t2][]=t1;dep[t2]=dep[t1]+;
  49. b[t1].push_back(t2);b[t2].push_back(t1);
  50. skip:if(vis[v]) continue;
  51. dfs(v);
  52. }
  53. return;
  54. }
  55. void init(){
  56. int i,j;
  57. for(j=;j<;j++){
  58. for(i=;i<n+cnt;i++){
  59. if(!b[i].size()) continue;
  60. p[i][j]=p[p[i][j-]][j-];
  61. }
  62. }
  63. }
  64. void shrink(){
  65. int i,j;
  66. for(i=;i<=n;i++){
  67. if(!dfn[i]) tarjan(i);
  68. }
  69. memset(vis,,sizeof(vis));memset(viss,,sizeof(viss));
  70. dep[color[]]=;p[color[]][]=color[];dfs();
  71. init();
  72. return ;
  73. }
  74. ll calc(int k,int to){
  75. if(k==to) return (to>n)?:;
  76. else return calc(p[k][],to)*((k>n)?:);
  77. }
  78. ll lca(int l,int r){
  79. int i,lca,tl=l,tr=r;
  80. if(dep[l]<dep[r]) swap(l,r);
  81. int diff=dep[l]-dep[r];
  82. for(i=;i<;i++){
  83. if(diff&(<<i)) l=p[l][i];
  84. }
  85. if(l==r) lca=l;
  86. else{
  87. for(i=;i>=;i--){
  88. if(p[l][i]!=p[r][i]){
  89. l=p[l][i];r=p[r][i];
  90. }
  91. }
  92. lca=p[l][];
  93. }
  94. return calc(tl,lca)*calc(tr,lca)/((lca>n)?:);
  95. }
  96. int main(){
  97. int i,t1,t2;
  98. scanf("%d%d",&n,&m);
  99. for(i=;i<=n;i++) color[i]=i;
  100. for(i=;i<=m;i++){
  101. scanf("%d%d",&t1,&t2);
  102. a[t1].push_back(t2);a[t2].push_back(t1);
  103. }
  104. shrink();
  105. scanf("%d",&q);
  106. for(i=;i<=q;i++){
  107. scanf("%d%d",&t1,&t2);
  108. printf("%lld\n",lca(color[t1],color[t2])%MOD);
  109. }
  110. }

JZOJ 5305 C先生的更多相关文章

  1. JZOJ 5305. 【NOIP2017提高A组模拟8.18】C (Standard IO)

    5305. [NOIP2017提高A组模拟8.18]C (Standard IO) Time Limits: 1000 ms Memory Limits: 131072 KB Description ...

  2. JZOJ.5305【NOIP2017模拟8.18】C

    Description

  3. (jzoj snow的追寻)线段树维护树的直径

    jzoj snow的追寻 DFS序上搞 合并暴力和,记录最长链和当前最远点,距离跑LCA # include <stdio.h> # include <stdlib.h> # ...

  4. [jzoj]3506.【NOIP2013模拟11.4A组】善良的精灵(fairy)(深度优先生成树)

    Link https://jzoj.net/senior/#main/show/3506 Description 从前有一个善良的精灵. 一天,一个年轻人B找到她并请他预言他的未来.这个精灵透过他的水 ...

  5. [jzoj]3468.【NOIP2013模拟联考7】OSU!(osu)

    Link https://jzoj.net/senior/#main/show/3468 Description osu 是一款群众喜闻乐见的休闲软件. 我们可以把osu的规则简化与改编成以下的样子: ...

  6. [jzoj]5478.【NOIP2017提高组正式赛】列队

    Link https://jzoj.net/senior/#main/show/5478 Description Sylvia 是一个热爱学习的女孩子.       前段时间,Sylvia 参加了学校 ...

  7. [jzoj]1115.【HNOI2008】GT考试

    Link https://jzoj.net/senior/#main/show/1115 Description 申准备报名参加GT考试,准考证号为n位数X1X2X3...Xn-1Xn(0<=X ...

  8. [jzoj]2538.【NOIP2009TG】Hankson 的趣味题

    Link https://jzoj.net/senior/#main/show/2538 Description Hanks 博士是BT (Bio-Tech,生物技术) 领域的知名专家,他的儿子名叫H ...

  9. [jzoj]4216.【NOIP2015模拟9.12】平方和

    Link https://jzoj.net/senior/#main/show/4216 Description 给出一个N个整数构成的序列,有M次操作,每次操作有一下三种: ①Insert Y X, ...

随机推荐

  1. 使用免费公开的api接口示例(iOS)

    做项目难免需要测试,要测试就需要一些接口,现在网上的很多接口都是需要收费的. 以下是目前找到的免费 JSON API免费接口 云聚数据 网吧数据 其中选取了一个百度百科的接口 百度接口 百度百科接口: ...

  2. leetcode第221题(最大正方形)的本地IDE实现及变形

    问题描述: 在一个由 0 和 1 组成的二维矩阵内,找到只包含 1 的最大正方形,并返回其面积.PS:本文也对只包含0的最大正方形面积进行了运算 示例: 输入: 1 0 1 0 0 1 0 1 1 1 ...

  3. 网页更换主题以及绘制图形js代码实现

    HTML代码实现: <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  4. MySQL中使用group_concat()函数数据被截取(有默认长度限制),谨慎!

    最近在工作中遇到一个问题: 我们系统的一些逻辑处理是用存储过程实现的,但是有一天客服反馈说订单下单失败,查了下单牵扯到的产品基础资源,没有问题. 下单的存储过程中有这样两句代码: ; ; ; 执行存储 ...

  5. Centos7安装Mysql5.7并修改初始密码

    1.CentOS 的yum源中没有mysql,需要到mysql的官网下载yum repo配置文件. wget https://dev.mysql.com/get/mysql57-community-r ...

  6. [Codeforces967C]Stairs and Elevators(二分查找)

    [不稳定的传送门] Sloution 每次试一下最近的2个楼梯或者电梯就行了 Code #include <cstdio> #include <algorithm> #incl ...

  7. python-7面向对象高级编程

    1-给类动态增加方法 class Student(object): pass def set_score(self, score): self.score = score Student.set_sc ...

  8. Git-Git克隆

    鸡蛋不装在一个篮子里 Git的版本库目录和工作区在一起,因此存在一损俱损的问题,即如果删除一个项目的工作区,同时也会把这个项目的版本库删除掉.一个项目仅在一个工作区中维护太危险了,如果有两个工作区就会 ...

  9. POJ 3461 Oulipo(字符串hash)

    题目链接 字符串hash判断字符串是否相等. code #include<cstdio> #include<algorithm> #include<cstring> ...

  10. Android ANR详解

    如何避免KeyDispatchTimeout 1:UI线程尽量只做跟UI相关的工作 2:耗时的工作(比如数据库操作,I/O,连接网络或者别的有可能阻碍UI线程的操作)把它放入单独的线程处理 3:尽量用 ...