E. Cactus
 

A connected undirected graph is called a vertex cactus, if each vertex of this graph belongs to at most one simple cycle.

A simple cycle in a undirected graph is a sequence of distinct vertices v1, v2, ..., vt (t > 2), such that for any i (1 ≤ i < t) exists an edge between vertices vi and vi + 1, and also exists an edge between vertices v1 and vt.

A simple path in a undirected graph is a sequence of not necessarily distinct vertices v1, v2, ..., vt (t > 0), such that for any i (1 ≤ i < t)exists an edge between vertices vi and vi + 1 and furthermore each edge occurs no more than once. We'll say that a simple pathv1, v2, ..., vt starts at vertex v1 and ends at vertex vt.

You've got a graph consisting of n vertices and m edges, that is a vertex cactus. Also, you've got a list of k pairs of interesting verticesxi, yi, for which you want to know the following information — the number of distinct simple paths that start at vertex xi and end at vertex yi. We will consider two simple paths distinct if the sets of edges of the paths are distinct.

For each pair of interesting vertices count the number of distinct simple paths between them. As this number can be rather large, you should calculate it modulo 1000000007 (109 + 7).

Input

The first line contains two space-separated integers n, m (2 ≤ n ≤ 105; 1 ≤ m ≤ 105) — the number of vertices and edges in the graph, correspondingly. Next m lines contain the description of the edges: the i-th line contains two space-separated integers ai, bi (1 ≤ ai, bi ≤ n) — the indexes of the vertices connected by the i-th edge.

The next line contains a single integer k (1 ≤ k ≤ 105) — the number of pairs of interesting vertices. Next k lines contain the list of pairs of interesting vertices: the i-th line contains two space-separated numbers xiyi (1 ≤ xi, yi ≤ nxi ≠ yi) — the indexes of interesting vertices in the i-th pair.

It is guaranteed that the given graph is a vertex cactus. It is guaranteed that the graph contains no loops or multiple edges. Consider the graph vertices are numbered from 1 to n.

Output

Print k lines: in the i-th line print a single integer — the number of distinct simple ways, starting at xi and ending at yi, modulo1000000007 (109 + 7).

Examples
input
10 11
1 2
2 3
3 4
1 4
3 5
5 6
8 6
8 7
7 6
7 9
9 10
6
1 2
3 5
6 9
9 2
9 3
9 10
output
2
2
2
4
4
1

 题意:

   给你n个点,m条边的无向图,给出下面定义

  一般简单路的定义是一条无重复边和不经过重复点的路径,题述的定义是:可以经过重复点但无重复边的路径  

  无向图中的任意一点只属于一个简单环,然后询问任何两点间有多少条不同的简单路。

题解:  

  任意一点只属于一个简单环

  我们先缩环

  每个环当做点,那么在询问a到b的时候,环中点个数超过1的时候 就是存在两种走法,否则是1种,这个我们将它当作点权就好

  就相当于 求出一个树的LCA和点权乘

  每个点权求法和求lca中fa数组是一样的

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define pii pair<int,int>
#define MP make_pair
typedef long long LL;
const long long INF = 1e18;
const double Pi = acos(-1.0);
const int N = 1e5+, M = 1e6, mod = 1e9+, inf = 2e9; int n,m,low[N],dfn[N],inq[N],q[N],top,tot,t,head[N],hav[N],scc,belong[N]; struct node{int to,next,id;}e[N * ];
void add(int u,int v) {e[t].next=head[u];e[t].to=v;e[t].id=;head[u]=t++;} int dp[N][],fa[N][],dep[N];
vector<int > G[N];
void dfs(int u) {
dfn[u] = low[u] = ++tot;
q[++top] = u; inq[u] = ;
for(int i = head[u]; i; i = e[i].next) {
int to = e[i].to;
if(e[i].id) continue;
e[i].id = e[i^].id = ;
if(!dfn[to]) {
dfs(to);
low[u] = min(low[u],low[to]);
} else if(inq[to]) low[u] = min(low[u],dfn[to]);
}
if(low[u] == dfn[u]) {
scc++;
do{
inq[q[top]] = ;
belong[q[top]] = scc;
hav[scc] += ;
} while(u != q[top--]);
}
}
void rebuild() {
for(int i = ; i <= n; ++i) {
for(int j = head[i]; j; j = e[j].next) {
int to = e[j].to;
int x = belong[to];
int y = belong[i];
if(x != y) {
G[x].push_back(y);
}
}
}
}
void Tarjan() {
for(int i = ; i <= n; ++i) if(!dfn[i]) dfs(i);
rebuild();
for(int i = ; i <= scc; ++i) hav[i] = min(hav[i],);
} ////
void lca_dfs(int u,int p,int d) {
fa[u][] = p, dep[u] = d;
dp[u][] = hav[u];
for(int i = ; i < G[u].size(); ++i) {
int to = G[u][i];
if(to == p) continue;
lca_dfs(to,u,d+);
}
}
void lca_init() {
for(int i = ; i <= ; ++i) {
for(int j = ; j <= n; ++j) {
if(fa[j][i-]) {
dp[j][i] = (1ll * dp[j][i-] * dp[fa[j][i-]][i-]) % mod;
fa[j][i] = fa[fa[j][i-]][i-];
} else {
fa[j][i] = ;
dp[j][i] = ;
}
}
}
}
int lca(int x,int y) {
if(dep[x] > dep[y]) swap(x,y);
int ret = ;
for(int k = ; k < ; ++k) {
if( (dep[y] - dep[x])>>k & )
ret = 1LL * ret * dp[y][k] % mod, y = fa[y][k];
}
if(x == y) return 1LL * ret * hav[x] % mod;
for(int k = ; k >= ; --k) {
if(fa[x][k] != fa[y][k]) {
ret = 1LL * ret * dp[x][k] % mod;
ret = 1LL * ret * dp[y][k] % mod;
x = fa[x][k];
y = fa[y][k];
}
}
return 1LL * ret * dp[x][] % mod * dp[y][] % mod * hav[fa[x][]]% mod;
}
int main() {
scanf("%d%d",&n,&m);
for(int i = ; i <= m; ++i) {
int a,b;
scanf("%d%d",&a,&b);
add(a,b);
add(b,a);
}
Tarjan();
lca_dfs(,,);
lca_init();
int q;
scanf("%d",&q);
while(q--) {
int a,b;
scanf("%d%d",&a,&b);
if(belong[a] == belong[b]) {
puts("");continue;
}
printf("%d\n",lca(belong[a],belong[b]));
}
return ;
}

  

Codeforces Round #143 (Div. 2) E. Cactus 无向图缩环+LCA的更多相关文章

  1. Codeforces Round #143 (Div. 2)

    A. Team 模拟. B. Magic, Wizardry and Wonders 可以发现\[d=a_1-a_2+a_3-a_4+\cdots\] 那么有\(odd=\lfloor \frac{n ...

  2. Codeforces Round #143 (Div. 2) (ABCD 思维场)

    题目连链接:http://codeforces.com/contest/231 A. Team time limit per test:2 seconds memory limit per test: ...

  3. codeforces水题100道 第十一题 Codeforces Round #143 (Div. 2) A. Team (brute force)

    题目链接:http://www.codeforces.com/problemset/problem/231/A题意:问n道题目当中有多少道题目是至少两个人会的.C++代码: #include < ...

  4. Codeforces Round #362 (Div. 2) C. Lorenzo Von Matterhorn (类似LCA)

    题目链接:http://codeforces.com/problemset/problem/697/D 给你一个有规则的二叉树,大概有1e18个点. 有两种操作:1操作是将u到v上的路径加上w,2操作 ...

  5. Codeforces Round #343 (Div. 2) E. Famil Door and Roads lca 树形dp

    E. Famil Door and Roads 题目连接: http://www.codeforces.com/contest/629/problem/E Description Famil Door ...

  6. Codeforces Round #425 (Div. 2) Misha, Grisha and Underground(LCA)

    Misha, Grisha and Underground time limit per test 2 seconds memory limit per test 256 megabytes inpu ...

  7. Codeforces Round #111 (Div. 2)

    Codeforces Round #111 (Div. 2) C. Find Pair 题意 给\(N(N \le 10^5)\)个数,在所有\(N^2\)对数中求第\(K(K \le N^2)\)对 ...

  8. Codeforces Round #485 (Div. 2)

    Codeforces Round #485 (Div. 2) https://codeforces.com/contest/987 A #include<bits/stdc++.h> us ...

  9. Codeforces Round #296 (Div. 1) C. Data Center Drama 欧拉回路

    Codeforces Round #296 (Div. 1)C. Data Center Drama Time Limit: 2 Sec  Memory Limit: 256 MBSubmit: xx ...

随机推荐

  1. XsltListViewWebPart 和自定义列表视图

    http://msdn.microsoft.com/zh-cn/library/ff806162(v=office.14).aspx

  2. 比较两个mysql数据库表结构的差异

    需求来源:一个线上系统,一个开发系统,现在要把开发系统更新到线上,但是开发系统的数据库结构与线上的略有差异,所以需要找出两个数据库的表结构差异. 数据库表结构的差异 注:操作均在Linux系统下完成 ...

  3. Urllib2 总结

    Urllib2 总结 介绍 Urllib2是用于获取URLs(统一资源定位符)的一个Python模块.它以urlopen函数的形式提供了非常简单的接口.能够使用各种不同的协议来获取网址.它还提供一个稍 ...

  4. Effective C++ -----条款44:将与参数无关的代码抽离templates

    Templates生成多个classes和多个函数,所以任何template代码都不该与某个造成膨胀的template参数产生相依关系. 因非类型模板参数(non-type template para ...

  5. KMP单模快速字符串匹配算法

    KMP算法是由Knuth,Morris,Pratt共同提出的算法,专门用来解决模式串的匹配,无论目标序列和模式串是什么样子的,都可以在线性时间内完成,而且也不会发生退化,是一个非常优秀的算法,时间复杂 ...

  6. DX使用texconv工具批处理dds格式图片

    texconv D:\png\*.* -o E:\dds -m 5 -f dxt3 -ft dds 上述命令的意思是把D:\png目录下的全部文件(当然可以指定特定格式例如*.png)转换成dds格式 ...

  7. SQL Server多表多列更新

    student表: lag表: 要求将student表stu_id列为1的stu_nick列和stu_phont列的数据更新为lag表的lag_nick列和lag_phone列. SQL语句: upd ...

  8. android viewPager 切换页面时防止fragment重新加载

    把限制页面数设置成应用一共的页面数就可以了 ViewPager.setOffscreenPageLimit(3);

  9. Swift - 文件目录路径获取及数据储存(Home目录,文档目录,缓存目录)

    iOS应用程序只能在自己的目录下进行文件的操作,不可以访问其他的存储空间,此区域被称为沙盒.   应用沙盒结构分析 1.应用程序包:包含了所有的资源文件和可执行文件 2.Documents:保存应用运 ...

  10. mysql 查看用户的权限

    show grants for 'username'@'%';