[noi706]Sabotage

First of all may be the degree of a node is connected to a zero point, then the problem becomes point must pass through this point to seek
fact, this is a template problem, because there is a thing called dominant tree
is easy to find a point to go through the point is a chain, in fact, can put chains on the shallowest point as the father of this point, then all must pass through a point clearly point is the point on his path to the root
specifically, this point of father is lca all his points Unicom (can not be called lca, topology can be used to seek)
lca depth eventually dominate the tree asked the two points is the answer

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 100005
 4 queue<int>q;
 5 vector<int>a[N],b[N];
 6 int n,m,x,y,vis[N],sh[N],f[N][21];
 7 int lca(int x,int y){
 8     if (sh[x]<sh[y])swap(x,y);
 9     for(int i=20;i>=0;i--)
10         if (sh[x]-(1<<i)>=sh[y])x=f[x][i];
11     if (x==y)return x;
12     for(int i=20;i>=0;i--)
13         if (f[x][i]!=f[y][i]){
14             x=f[x][i];
15             y=f[y][i];
16         }
17     return f[x][0];
18 }
19 int main(){
20     scanf("%d%d",&n,&m);
21     for(int i=1;i<=m;i++){
22         scanf("%d%d",&x,&y);
23         a[x].push_back(y);
24         b[y].push_back(x);
25         vis[x]++;
26     }
27     for(int i=1;i<=n;i++)
28         if (!vis[i])q.push(i);
29     while (!q.empty()){
30         int k=q.front();
31         q.pop();
32         int v=0;
33         if (a[k].size()){
34             v=a[k][0];
35             for(int i=1;i<a[k].size();i++)v=lca(v,a[k][i]);
36         }
37         sh[k]=sh[v]+1;
38         f[k][0]=v;
39         for(int i=1;i<=20;i++)f[k][i]=f[f[k][i-1]][i-1];
40         for(int i=0;i<b[k].size();i++)
41             if (--vis[b[k][i]]==0)q.push(b[k][i]);
42     }
43     scanf("%d",&m);
44     for(int i=1;i<=m;i++){
45         scanf("%d%d",&x,&y);
46         printf("%d\n",sh[lca(x,y)]);
47     }
48 }
View Code

 

Guess you like

Origin www.cnblogs.com/PYWBKTDA/p/11617711.html