poj 3694 Network (桥入门)

  1 /********************************************
  2     Network(POJ 3694)
  3     http://poj.org/problem?id=3694
  4     桥入门题 + LCA(树中最小公共祖先)
  5     做这题必须要会用邻接表(做这题才学会),因为
  6     给的边有重边,用vector不好记录重边。
  7
  8 ********************************************/
  9
 10 #include<iostream>
 11 #include<algorithm>
 12 #include<cstring>
 13 #include<cstdio>
 14 using namespace std;
 15
 16 const int M=100005;
 17
 18 struct Eage                ///邻接表建图
 19 {
 20     int v;
 21     int next;
 22     int vs;
 23 };
 24
 25 Eage eage[M*4];
 26 int low[M],dfn[M],father[M];  ///father[i]为i的父亲节点
 27 int flag[M],vs[M],head[M];    ///falg[i]为i和i的父亲节点的边
 28 int dfs_cut,ans,k;
 29
 30 void Init()
 31 {
 32     memset(dfn,0,sizeof(dfn));
 33     memset(low,0,sizeof(low));
 34     memset(flag,0,sizeof(flag));
 35     memset(vs,0,sizeof(vs));
 36     memset(head,-1,sizeof(head));
 37     dfs_cut=ans=k=0;
 38 }
 39
 40 void add(int u,int v)
 41 {
 42     eage[k].v=v;
 43     eage[k].vs=0;
 44     eage[k].next=head[u];
 45     head[u]=k++;
 46 }
 47
 48 void dfs(int u)                     ///求桥
 49 {
 50     vs[u]=1;
 51     dfn[u]=low[u]=++dfs_cut;
 52     for (int i=head[u];i!=-1;i=eage[i].next)
 53     {
 54         if (!eage[i].vs)
 55         {
 56             eage[i].vs=eage[i^1].vs=1;
 57             int v=eage[i].v;
 58             if (!vs[v])
 59             {
 60                 father[v]=u;
 61                 dfs(v);
 62                 low[u]=min(low[u],low[v]);
 63                 if (dfn[u]<low[v])
 64                 {
 65                     ans++;
 66                     flag[v]=1;
 67                 }
 68             }
 69             else low[u]=min(low[u],dfn[v]);
 70         }
 71     }
 72 }
 73
 74 void Lca(int u,int v)
 75 {
 76     if (dfn[u]<dfn[v])
 77     {
 78         u^=v;
 79         v^=u;
 80         u^=v;
 81     }
 82     while (dfn[u]>dfn[v])
 83     {
 84         if (flag[u]) ans--;
 85         flag[u]=0;
 86         u=father[u];
 87     }
 88     while (u!=v)
 89     {
 90         if (flag[v]) ans--;
 91         if (flag[u]) ans--;
 92         flag[u]=0;
 93         flag[v]=0;
 94         v=father[v];
 95         u=father[u];
 96     }
 97 }
 98
 99 int main()
100 {
101   //  freopen("C://Users//Administrator//Desktop//in.txt","r",stdin);
102    // freopen("C://Users//Administrator//Desktop//out.txt","w",stdout);
103     int n,m,cut=0;
104     while (cin>>n>>m)
105     {
106         if (!n&&!m) return 0;
107         Init();
108         for (int i=1;i<=n;i++) father[i]=i;
109         int u,v;
110         while (m--)
111         {
112             cin>>u>>v;
113             add(u,v);
114             add(v,u);
115         }
116         dfs(1);
117         cout<<"Case "<<++cut<<":"<<endl;
118         int q;
119         cin>>q;
120         while (q--)
121         {
122             cin>>u>>v;
123             Lca(u,v);
124             cout<<ans<<endl;
125         }
126         cout<<endl;
127     }
128     return 0;
129 }
时间: 2024-08-07 16:38:12

poj 3694 Network (桥入门)的相关文章

Poj 3694 Network (连通图缩点+LCA+并查集)

题目链接: Poj 3694 Network 题目描述: 给出一个无向连通图,加入一系列边指定的后,问还剩下多少个桥? 解题思路: 先求出图的双连通分支,然后缩点重新建图,加入一个指定的边后,求出这条边两个端点根节点的LCA,统计其中的桥,然后把这个环中的节点加到一个集合中,根节点标记为LCA. 题目不难,坑在了数组初始化和大小 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #inclu

POJ 3694——Network——————【连通图,LCA求桥】

Network Time Limit:5000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 3694 Description A network administrator manages a large network. The network consists of N computers and M links between pairs of compute

POJ 3694 Network ——(桥 + LCA)

题意:给n个点和m条边,再给出q条边,问每次加一条边以后剩下多少桥. 分析:这题是结合了LCA和dfn的妙用._dfn数组和dfn的意义不一样,并非访问的时间戳,_dfn表示的是被访问的顺序,而且是多线程访问下的顺序,举个例子,同一个点分岔开来的点,距离这个点相同距离的点,他们的_dfn的值是相同的,而dfn不是,类似于单线程dfs访问的各点的dfn值是不同的. 具体见代码: 1 #include <stdio.h> 2 #include <algorithm> 3 #includ

poj 3694 Network(桥+lca)

给定一个无向无环图,保证连通,求每加入一条给定的边图中还剩下多少桥. 双联通缩点重新建图后,再用lca在线算法解. lca算法参考斌神http://www.cnblogs.com/kuangbin/p/3184884.html 这个版本的lca思路大致是先topsort,再用并查集分别从查询的两点向根节点回溯,直到两个点碰撞.效率我分析不出来,但看得出效率很高,每次查询都对后面查询做了工作. 代码: #include<iostream> #include<cstdio> #incl

POJ 3694 Network(无向图求桥+重边处理+LCA)

题目大意: 给你一个无向图,然后再给你一个Q代表有Q次询问,每一次加一条边之后还有几座桥.在这里要对重边进行处理. 每次加入一条边之后,在这条搜索树上两个点的公共祖先都上所有点的桥都没了. 这里重边的处理上要说一下, 我以前第一写的时候根本没考虑这个问题,但是居然过了...过了...  很扯淡,但是重边的问题确实是存在. 这里我们 使用一个 bridge 数组来保存桥, 因为有重边的存在  只有 bridge 数量为 1 的时候这个路径才算是桥,否则则不是桥 bridge[i] 是指  i 和

POJ 3694 Network (tarjan + LCA)

题目链接:http://poj.org/problem?id=3694 题意是给你一个无向图n个点,m条边,将m条边连接起来之后形成一个图,有Q个询问,问将u和v连接起来后图中还有多少个桥. 首先用tarjan标记点的low和dfn值,那么u和v相连的边是桥的条件是dfn[u] < low[v](说明v与u不在一个连通分量里面,v无法通过回溯到达u点,画个图模拟会清楚).那么bridge[v]++表示u与v相连的边是桥(若是标记bridge[u]++,则最后的答案可能会出错,亲测).要是u和v相

[双连通分量] POJ 3694 Network

Network Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 9434   Accepted: 3511 Description A network administrator manages a large network. The network consists of N computers and M links between pairs of computers. Any pair of computers

POJ 3694 Network

Network Time Limit: 5000ms Memory Limit: 65536KB This problem will be judged on PKU. Original ID: 369464-bit integer IO format: %lld      Java class name: Main A network administrator manages a large network. The network consists of N computers and M

POJ 3694 tarjan 桥+lca

Network Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 7298   Accepted: 2651 Description A network administrator manages a large network. The network consists of N computers and M links between pairs of computers. Any pair of computers