Network(Tarjan+LCA)

元宵节+情人节晚上刷的题,纪念一下。。
题意:给出n个点,m条边,然后Q个询问,每次询问输入一条边,输出加入此边后桥的个数。。
  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 }
View Code

 

 
posted @ 2014-02-14 23:15  N_ll  阅读(268)  评论(0编辑  收藏  举报