逃不掉的路 CH Round #24 - 三体杯 Round #1

题目描述

现代社会,路是必不可少的。任意两个城镇都有路相连,而且往往不止一条。但有些路连年被各种XXOO,走着很不爽。按理说条条大路通罗马,大不了绕行其他路呗——可小撸却发现:从a城到b城不管怎么走,总有一些逃不掉的必经之路

他想请你计算一下,a到b的所有路径中,有几条路是逃不掉的?

输入格式

第一行是n和m,用空格隔开。接下来m行,每行两个整数x和y,用空格隔开,表示x城和y城之间有一条长为1的双向路。第m+2行是q。接下来q行,每行两个整数a和b,用空格隔开,表示一次询问。

输出格式

对于每次询问,输出一个正整数,表示a城到b城必须经过几条路。

样例输入

5 5

1 2

1 3

2 4

3 4

4 5

2

1 4

2 5

样例输出

0

1

样例解释

第1次询问,1到4的路径有 1--2--4 ,还有 1--3--4 。没有逃不掉的道路,所以答案是0。

第2次询问,2到5的路径有 2--4--5 ,还有 2--1--3--4--5 。必须走“4--5”这条路,所以答案是1。

数据约定与范围

共10组数据,每组10分。

有3组数据,n ≤ 100 , n ≤ m ≤ 200 , q ≤ 100。

另有2组数据,n ≤ 103 , n ≤ m ≤ 2 x 103 , 100 < q ≤ 105

另有3组数据,103 < n ≤ 105 , m = n-1 , 100 < q ≤ 105

另有2组数据,103 < n ≤ 105 , n ≤ m ≤ 2 x 105 , 100 < q ≤ 105

对于全部的数据,1 ≤ x,y,a,b ≤ n;对于任意的道路,两端的城市编号之差不超过104

任意两个城镇都有路径相连;同一条道路不会出现两次;道路的起终点不会相同;查询的两个城市不会相同。

题解

要求无向图的必经边,较为简单的做法是找出边双缩点,然后转化成树上距离问题。

  1. #include<bits/stdc++.h>
  2. #define rg register
  3. #define il inline
  4. #define co const
  5. template<class T>il T read(){
  6. rg T data=0,w=1;rg char ch=getchar();
  7. for(;!isdigit(ch);ch=getchar())if(ch=='-') w=-w;
  8. for(;isdigit(ch);ch=getchar()) data=data*10+ch-'0';
  9. return data*w;
  10. }
  11. template<class T>il T read(rg T&x) {return x=read<T>();}
  12. typedef long long ll;
  13. using namespace std;
  14. co int N=2e5+1;
  15. int n,m;
  16. int head[N],ver[N*2],next[N*2],tot=1;
  17. int dfn[N],low[N],c[N],num,dcc;
  18. bool bridge[N*2];
  19. int hc[N],vc[N*2],nc[N*2],tc=1;
  20. int d[N],f[N][18];
  21. queue<int> q;
  22. il void add(int x,int y){
  23. ver[++tot]=y,::next[tot]=head[x],head[x]=tot;
  24. }
  25. il void add_c(int x,int y){
  26. vc[++tc]=y,nc[tc]=hc[x],hc[x]=tc;
  27. }
  28. void tarjan(int x,int in_edge){
  29. dfn[x]=low[x]=++num;
  30. for(int i=head[x];i;i=::next[i]){
  31. int y=ver[i];
  32. if(!dfn[y]){
  33. tarjan(y,i);
  34. low[x]=min(low[x],low[y]);
  35. if(low[y]>dfn[x]) bridge[i]=bridge[i^1]=1;
  36. }
  37. else if(i!=(in_edge^1)) low[x]=min(low[x],dfn[y]);
  38. }
  39. }
  40. void dfs(int x){ // dye
  41. c[x]=dcc;
  42. for(int i=head[x];i;i=::next[i]){
  43. int y=ver[i];
  44. if(c[y]||bridge[i]) continue;
  45. dfs(y);
  46. }
  47. }
  48. void bfs(){
  49. }
  50. int lca(int x,int y){
  51. if(d[x]<d[y]) swap(x,y);
  52. for(int i=17;i>=0;--i)
  53. if(d[f[x][i]]>=d[y]) x=f[x][i];
  54. if(x==y) return x;
  55. for(int i=17;i>=0;--i)
  56. if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
  57. return f[x][0];
  58. }
  59. int main(){
  60. read(n),read(m);
  61. for(int x,y;m--;){
  62. read(x),read(y);
  63. add(x,y),add(y,x);
  64. }
  65. // 缩点建图
  66. for(int i=1;i<=n;++i)
  67. if(!dfn[i]) tarjan(i,0);
  68. for(int i=1;i<=n;++i)
  69. if(!c[i]) ++dcc,dfs(i);
  70. for(int i=2;i<=tot;++i){
  71. int x=ver[i^1],y=ver[i];
  72. if(c[x]!=c[y]) add_c(c[x],c[y]);
  73. }
  74. // 倍增lca预处理
  75. d[1]=1,q.push(1);
  76. while(q.size()){
  77. int x=q.front();q.pop();
  78. for(int i=hc[x];i;i=nc[i]){
  79. int y=vc[i];
  80. if(d[y]) continue;
  81. d[y]=d[x]+1,f[y][0]=x;
  82. for(int j=1;j<18;++j) f[y][j]=f[f[y][j-1]][j-1];
  83. q.push(y);
  84. }
  85. }
  86. // 处理询问
  87. read(m);
  88. for(int x,y;m--;){
  89. x=c[read<int>()],y=c[read<int>()];
  90. printf("%d\n",d[x]+d[y]-2*d[lca(x,y)]);
  91. }
  92. return 0;
  93. }

Traffic Real Time Query System

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3808    Accepted Submission(s): 759


Problem Description
City C is really a nightmare of all drivers for its traffic jams. To solve the traffic problem, the mayor plans to build a RTQS (Real Time Query System) to monitor all traffic situations. City C is made up of N crossings and M roads, and each road connects two crossings. All roads are bidirectional. One of the important tasks of RTQS is to answer some queries about route-choice problem. Specifically, the task is to find the crossings which a driver MUST pass when he is driving from one given road to another given road.
 

Input
There are multiple test cases.
For each test case:
The first line contains two integers N and M, representing the number of the crossings and roads.
The next M lines describe the roads. In those M lines, the ith line (i starts from 1)contains two integers Xi and Yi, representing that roadi connects crossing Xi and Yi (Xi≠Yi).
The following line contains a single integer Q, representing the number of RTQs.
Then Q lines follows, each describing a RTQ by two integers S and T(S≠T) meaning that a driver is now driving on the roads and he wants to reach roadt . It will be always at least one way from roads to roadt.
The input ends with a line of “0 0”.
Please note that: 0<N<=10000, 0<M<=100000, 0<Q<=10000, 0<Xi,Yi<=N, 0<S,T<=M
 

Output
For each RTQ prints a line containing a single integer representing the number of crossings which the driver MUST pass.
 

Sample Input
  1. 5 6
  2. 1 2
  3. 1 3
  4. 2 3
  5. 3 4
  6. 4 5
  7. 3 5
  8. 2
  9. 2 3
  10. 2 4
  11. 0 0
 

Sample Output
  1. 0
  2. 1
 

Source
 

Recommend
lcy&zhengfeng   |   We have carefully selected several similar problems for you:  3689 3682 3683 3681 3687 
 

给你一个无向图,询问边a和边b,问从边a到边b的路径中几个点是必须要经过的。

题解

求无向图的必经点,跟上题类似,求出点双后缩点,然后转化成查询路径上割点的个数。由于点双缩点的特殊性,所以算距离的时候写的不一样。

  1. #include<iostream>
  2. #include<cstring>
  3. #include<queue>
  4. #define rg register
  5. #define il inline
  6. #define co const
  7. template<class T>il T read(){
  8. rg T data=0,w=1;rg char ch=getchar();
  9. for(;!isdigit(ch);ch=getchar())if(ch=='-') w=-w;
  10. for(;isdigit(ch);ch=getchar()) data=data*10+ch-'0';
  11. return data*w;
  12. }
  13. template<class T>il T read(rg T&x) {return x=read<T>();}
  14. typedef long long ll;
  15. using namespace std;
  16. co int N=2e4+1,M=2e5+2;
  17. int n,m,t;
  18. int head[N],ver[M],next[M],tot;
  19. int dfn[N],low[N],stack[N],new_id[N],c[N],belong[M],num,root,top,cnt;
  20. int d[N],dist[N],f[N][16];
  21. bool cut[N];
  22. vector<int> dcc[N];
  23. int hc[N],vc[M],nc[M],tc;
  24. queue<int> q;
  25. il void add(int x,int y){
  26. ver[++tot]=y,::next[tot]=head[x],head[x]=tot;
  27. }
  28. il void add_c(int x,int y){
  29. vc[++tc]=y,nc[tc]=hc[x],hc[x]=tc;
  30. }
  31. void tarjan(int x){
  32. dfn[x]=low[x]=++num;
  33. stack[++top]=x;
  34. if(x==root&&head[x]==0){
  35. dcc[++cnt].push_back(x);
  36. return;
  37. }
  38. int flag=0;
  39. for(int i=head[x];i;i=::next[i]){
  40. int y=ver[i];
  41. if(!dfn[y]){
  42. tarjan(y);
  43. low[x]=min(low[x],low[y]);
  44. if(low[y]>=dfn[x]){
  45. ++flag;
  46. if(x!=root||flag>1) cut[x]=1;
  47. ++cnt;
  48. int z;
  49. do{
  50. z=stack[top--];
  51. dcc[cnt].push_back(z);
  52. }while(z!=y);
  53. dcc[cnt].push_back(x);
  54. }
  55. }
  56. else low[x]=min(low[x],dfn[y]);
  57. }
  58. }
  59. void bfs(int s){
  60. d[s]=1,dist[s]=s>cnt,q.push(s);
  61. for(int i=0;i<16;++i) f[s][i]=0;
  62. while(q.size()){
  63. int x=q.front();q.pop();
  64. for(int i=hc[x];i;i=nc[i]){
  65. int y=vc[i];
  66. if(d[y]) continue;
  67. d[y]=d[x]+1,dist[y]=dist[x]+(y>cnt),f[y][0]=x;
  68. for(int j=1;j<16;++j) f[y][j]=f[f[y][j-1]][j-1];
  69. q.push(y);
  70. }
  71. }
  72. }
  73. int lca(int x,int y){
  74. if(d[x]<d[y]) swap(x,y);
  75. for(int i=15;i>=0;--i)
  76. if(d[f[x][i]]>=d[y]) x=f[x][i];
  77. if(x==y) return x;
  78. for(int i=15;i>=0;--i)
  79. if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
  80. return f[x][0];
  81. }
  82. int main(){
  83. while(read(n)|read(m)){
  84. memset(head,0,sizeof head);
  85. memset(hc,0,sizeof hc);
  86. memset(dfn,0,sizeof dfn);
  87. memset(d,0,sizeof d);
  88. memset(cut,0,sizeof cut);
  89. memset(c,0,sizeof c);
  90. for(int i=1;i<=n;++i) dcc[i].clear();
  91. tot=1,num=cnt=top=0;
  92. for(int x,y;m--;){
  93. read(x),read(y);
  94. add(x,y),add(y,x);
  95. }
  96. for(int i=1;i<=n;++i)
  97. if(!dfn[i]) root=i,tarjan(i);
  98. num=cnt;
  99. for(int i=1;i<=n;++i)
  100. if(cut[i]) new_id[i]=++num;
  101. tc=1;
  102. for(int i=1;i<=cnt;++i){
  103. for(int j=0;j<dcc[i].size();++j){
  104. int x=dcc[i][j];
  105. if(cut[x]) add_c(i,new_id[x]),add_c(new_id[x],i);
  106. c[x]=i;
  107. }
  108. for(int j=0;j<dcc[i].size()-1;++j){
  109. int x=dcc[i][j];
  110. for(int k=head[x];k;k=::next[k]){
  111. int y=ver[k];
  112. if(c[y]==i) belong[k/2]=i; // 输入的第k/2条边(x,y)处于第i个v-DCC内
  113. }
  114. }
  115. }
  116. // 编号 1~cnt 的为原图的v-DCC,编号 cnt+1~num 的为原图割点
  117. for(int i=1;i<=num;++i)
  118. if(!d[i]) bfs(i);
  119. read(t);
  120. while(t--){
  121. int es=read<int>(),et=read<int>();
  122. int x=belong[es],y=belong[et],z=lca(x,y);
  123. printf("%d\n",dist[x]+dist[y]-2*dist[z]+(z>cnt));
  124. }
  125. }
  126. return 0;
  127. }

CH#24C 逃不掉的路 和 HDU3686 Traffic Real Time Query System的更多相关文章

  1. ContestHunter#24-C 逃不掉的路

    Description: 求无向图的必经边 思路:一眼题 将无向图缩成树,然后求两点树上距离 #include<iostream> #include<vector> #incl ...

  2. CH Round #24 - 三体杯 Round #1-C 逃不掉的路

    留个e-DCC的板子 #include<cstdio> #include<iostream> #include<cstring> #include<cstdl ...

  3. CH24C 逃不掉的路

    edcc缩点之后跳倍增lca 丢个edcc缩点模板 Code: #include <cstdio> #include <cstring> using namespace std ...

  4. 高并发第九弹:逃不掉的Map --> HashMap,TreeMap,ConcurrentHashMap

    平时大家都会经常使用到 Map,面试的时候又经常会遇到问Map的,其中主要就是 ConcurrentHashMap,在说ConcurrentHashMap.我们还是先看一下, 其他两个基础的 Map ...

  5. 逃不掉的mysql数据库安装方式大全yum rpm 源码

    数据库虽然也不是天天安装,但每次安装都要找来找去挺烦,特整理记录在此. 系统基于:Centos 7.x 数据库版本: MySQL 5.7.x 转载请注明出处 Yum 安装方式 1.下载 yum rep ...

  6. Spring Cloud实战 | 第十篇 :Spring Cloud + Seata 1.4.1 + Nacos1.4.0 整合实现微服务架构中逃不掉的话题分布式事务

    Seata分布式事务在线体验地址:https://www.youlai.store 本篇完整源码地址:https://github.com/hxrui/youlai-mall 有想加入开源项目开发的童 ...

  7. D8 双连通分量

    记得有个梗那一天,zw学生zzh大佬说逃不掉的路变成a不掉的题哈哈哈哈: 分离的路径: BZOJ 1718POJ 3177LUOGU 286: 思路:在同一个边双连通分量中,任意两点都有至少两条独立路 ...

  8. 『Tarjan算法 无向图的双联通分量』

    无向图的双连通分量 定义:若一张无向连通图不存在割点,则称它为"点双连通图".若一张无向连通图不存在割边,则称它为"边双连通图". 无向图图的极大点双连通子图被 ...

  9. 边的双联通+缩点+LCA(HDU3686)

    Traffic Real Time Query System Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ...

随机推荐

  1. uitableview滚动到最后一行

    本文转载至 http://mrjeye.iteye.com/blog/1278521 - (void)scrollTableToFoot:(BOOL)animated { NSInteger s = ...

  2. 使用 Xcode 5 生成和使用静态库

      本文转载至 http://blog.csdn.net/qq331436155/article/details/18363267   静态库Static Libraryiosxcode   在项目中 ...

  3. 【BZOJ4537】[Hnoi2016]最小公倍数 分块

    [BZOJ4537][Hnoi2016]最小公倍数 Description 给定一张N个顶点M条边的无向图(顶点编号为1,2,…,n),每条边上带有权值.所有权值都可以分解成2^a*3^b的形式.现在 ...

  4. 7.FactoryBean 和BeanFactory去区别

    FactoryBean源码: /* * Copyright 2002-2012 the original author or authors. * * Licensed under the Apach ...

  5. bilingual evaluation understudy

    BLEU is designed to approximate human judgement at a corpus level, and performs badly if used to eva ...

  6. DNN优势

  7. Surpassing Human-Level Face Verification Performance on LFW with GaussianFace

    Face verification remains a challenging problem in very complex conditions with large variations suc ...

  8. perl智能匹配

    1.perl中~~为智能匹配,它能够智能地依据符号两側的操作数来确定操作. 如要推断某个元素是否存在于数组中,不使用智能匹配,程序像这样: my $x=2; my @array=(1,2,3); my ...

  9. ABAP--关于字符串String到XString XString to String转换代码

    转自http://guanhuaing.iteye.com/blog/1498891 代码如下 report zrich_0001. data: s type string, h(1) type x, ...

  10. 小程序连接百度ai

    function getTextFromImage(res) { var access_token = '24.c649256d2e*****0.282335-11449805'; var url = ...