题目:
Country A and B are at war. Country A needs to organize transport teams to deliver supplies toward some command center cities.
In order to ensure the delivery works efficiently, all the roads in country A work only one direction. Therefore, map of country A can be regarded as DAG( Directed Acyclic Graph ). Command center cities only received supplies and not send out supplies.
Intelligence agency of country B is credibly informed that there will be two cities carrying out a critical transporting task in country A.
As long as **any** one of the two cities can not reach a command center city, the mission fails and country B will hold an enormous advantage. Therefore, country B plans to destroy one of the nn cities in country A and all the roads directly connected. (If a city carrying out the task is also a command center city, it is possible to destroy the city to make the mission fail)
Now country B has made qq hypotheses about the two cities carrying out the critical task.
Calculate the number of plan that makes the mission of country A fail.
Input
The first line contains a integer TT (1≤T≤10)(1≤T≤10), denoting the number of test cases.
In each test case, the first line are two integers n,mn,m, denoting the number of cities and roads(1≤n≤100,000,1≤m≤200,000)(1≤n≤100,000,1≤m≤200,000).
Then mm lines follow, each with two integers uu and vv, which means there is a directed road from city uu to vv (1≤u,v≤n,u≠v)(1≤u,v≤n,u≠v).
The next line is a integer q, denoting the number of queries (1≤q≤100,000)(1≤q≤100,000)
And then qq lines follow, each with two integers aa and bb, which means the two cities carrying out the critical task are aa and bb (1≤a,b≤n,a≠b)(1≤a,b≤n,a≠b).
A city is a command center if and only if there is no road from it (its out degree is zero).
Output
For each query output a line with one integer, means the number of plan that makes the mission of country A fail.
Sample Input
2
8 8
1 2
3 4
3 5
4 6
4 7
5 7
6 8
7 8
2
1 3
6 7
3 2
3 1
3 2
2
1 2
3 1
Sample Output
4
3
2
2
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
#include<vector>
#include<map>
using namespace std;
const int maxn = 100005;
const int maxm = 300005;
const int LOG = 18;
struct Edge{
int to,nxt;
}edge1[maxm],edge2[maxm],edge3[maxm];
int tot1,tot2,tot3;
int head1[maxm], head2[maxm], head3[maxm];
void addEdge1(int u, int v)
{
edge1[tot1] = Edge{v,head1[u]};
head1[u] = tot1++;
}
void addEdge2(int u, int v)
{
edge2[tot2] = Edge{v,head2[u]};
head2[u] = tot2++;
}
void addEdge3(int u, int v)
{
edge3[tot3] = Edge{v,head3[u]};
head3[u] = tot3++;
}
int n, m;
int deg[maxn];
int depth[maxn];
int p[maxn]; //拓扑序
int f[maxn][LOG];
queue<int>q;
void init()
{
tot1 = tot2 = tot3 = 1;
memset(head1,-1,sizeof(head1));
memset(head2,-1,sizeof(head2));
memset(head3,-1,sizeof(head3));
memset(deg,0,sizeof(deg));
memset(f,0,sizeof(f));
memset(depth,0,sizeof(depth));
}
void topsort()
{
for(int i = 1; i <= n; i++)
{
if(!deg[i])
{
addEdge1(0,i);
addEdge2(i,0);
deg[i]++;
}
}
q.push(0);
int l=0;
while(!q.empty())
{
int u =q.front();
// cout << "## "<<u<<endl;
q.pop();
p[++l] = u;
for(int i = head1[u]; ~i; i = edge1[i].nxt)
{
int v = edge1[i].to;
deg[v]--;
if(!deg[v]) q.push(v);
}
}
}
int lca(int u, int v)
{
if(depth[u]<depth[v])
swap(u,v);
for(int i = LOG-1; i >= 0; i--)
{
if(depth[f[u][i]]>=depth[v])
u = f[u][i];
}
if(u==v)
return u;
for(int i = LOG-1; i >=0; i--)
{
if(f[u][i]!=f[v][i])
{
u = f[u][i];
v = f[v][i];
}
}
return f[u][0];
}
int main()
{
// cout << log(maxn)<<endl;
int t;
scanf("%d", &t);
while(t--)
{
init();
scanf("%d%d", &n, &m);
int u, v;
for(int i = 1; i <= m; i++)
{
scanf("%d%d", &u, &v);
addEdge1(v,u);
addEdge2(u,v);
deg[u]++;
}
topsort();
// for(int i = 1; i <= n+1; i++)
// cout << p[i]<<" ";
// cout << endl;
depth[0] = 0;
for(int i = 2; i<= n+1; i++)
{
u = p[i];
int fa = -1;
for(int j = head2[u]; ~j; j = edge2[j].nxt)
{
v = edge2[j].to;
if(fa==-1)
fa = v;
else
fa = lca(fa,v);
}
f[u][0] = fa;
depth[u] = depth[fa]+1;
addEdge3(fa,u);
for(int j = 1; j < LOG; j++)
f[u][j] = f[f[u][j-1]][j-1];
}
int q;
scanf("%d", &q);
while(q--)
{
scanf("%d%d", &u, &v);
// cout << depth[u]<<" "<<depth[v]<<" "<<depth[lca(u,v)]<<endl;
printf("%d\n", depth[u]+depth[v]-depth[lca(u,v)]);
}
}
return 0;
}