Network(Tarjan+LCA)
1 #include <stdio.h> 2 #include <string.h> 3 #include <queue> 4 #include <algorithm> 5 #include <stack> 6 const int N=205000; 7 using namespace std; 8 struct node 9 { 10 int u,v,w; 11 int next; 12 } edge[N*2]; 13 //dfn[i]表示点i的深度优先数; 14 int dfn[N],low[N],head[N]; //low[i]表示点i可到达的最低深度优先数 15 int vis[N],bridge[N],f[N]; 16 int n,m,cnt,dfs_clock,Conn_cnt; 17 int ans ; 18 stack<int>S; 19 20 void init() 21 { 22 ans = 0; 23 cnt = 0; 24 dfs_clock = 0; 25 Conn_cnt = 0; 26 for (int i = 0; i <= n; i++) 27 f[i] = i; 28 memset(dfn,0,sizeof(dfn)); 29 memset(low,0,sizeof(low)); 30 memset(vis,0,sizeof(vis)); 31 memset(head,-1,sizeof(head)); 32 } 33 void add(int u,int v) 34 { 35 edge[cnt].v = v; 36 edge[cnt].next = head[u]; 37 head[u] = cnt++; 38 edge[cnt].v = u; 39 edge[cnt].next = head[v]; 40 head[v] =cnt++; 41 } 42 43 void dfs(int u)//Tarjan算法 44 { 45 vis[u] = 1; 46 dfn[u]=low[u]=++dfs_clock;//设定初值 47 S.push(u);//将节点u压入栈中 48 for (int i = head[u]; i!=-1; i=edge[i].next)//遍历u的临接点 49 { 50 int v = edge[i].v; 51 if (!vis[v])//如果改点的深度优先数为0(即没有搜索过) 52 { 53 f[v] = u;//记录父节点 54 dfs(v);//继续向下找 55 low[u] = min(low[u],low[v]);//回溯过程中计算low[]的值 56 if(low[v] > dfn[u]) 57 { 58 ans++; 59 bridge[v] = 1;//标记点u->v为桥 60 } 61 } 62 else if(vis[v]==1&&v!=f[u]) 63 { 64 low[u] = min(low[u],dfn[v]); 65 } 66 } 67 vis[u] = 2; 68 } 69 void LCA(int u,int v) 70 { 71 if (dfn[u] < dfn[v]) 72 swap(u,v); 73 while(dfn[u] > dfn[v]) 74 { 75 if (bridge[u]) 76 { 77 ans--; 78 bridge[u] = 0; 79 } 80 u = f[u]; 81 } 82 while(u!=v) 83 { 84 if (bridge[u]) 85 { 86 ans--; 87 bridge[u] = 0; 88 } 89 if (bridge[v]) 90 { 91 ans--; 92 bridge[v] = 0; 93 } 94 u = f[u]; 95 v = f[v]; 96 } 97 } 98 int main() 99 { 100 int u,v,o = 0; 101 while(~scanf("%d%d",&n,&m)) 102 { 103 if (n==0&&m==0) 104 break; 105 init(); 106 o++; 107 for (int i = 0; i < m; i++) 108 { 109 scanf("%d%d",&u,&v); 110 add(u,v); 111 } 112 dfs(1); 113 int t; 114 scanf("%d",&t); 115 printf("Case %d:\n",o); 116 while(t--) 117 { 118 scanf("%d%d",&u,&v); 119 LCA(u,v); 120 printf("%d\n",ans); 121 } 122 puts(""); 123 } 124 return 0; 125 }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。