题意: 添加每条新连接后网络中桥的数目
// 超时 先放着了 ,下次改
//早上这代码超时了 下午改了,代码在下面
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <string.h>
using namespace std;
#define MOD 1000000007
#define maxn 440000
#define maxm 100010
struct Edge{
int to;
int num;
int next;
Edge(){};
Edge(int u,int v){to=u;next=v;}
}E[maxn];
int V[maxm],num;
bool tag[maxn];
int pre[maxm];
int dfst,bcc;
int ans,eg;
void init(int n){
eg=;
dfst=;
num=;
bcc=;
for(int i=;i<=n;i++)
V[i]=-;
}
void add(int u,int v){ // 坑爹 原来原图没有重边的 郁闷 ,这里就耗了不少时间
int e;
for(e=V[u];e!=-;e=E[e].next)
{
if(v==E[e].to){
tag[E[e].num]=;return;
}
}
eg++;
E[num].to=v;
E[num].num=eg;
E[num].next=V[u];
V[u]=num++; E[num].to=u;
E[num].num=eg;
E[num].next=V[v];
V[v]=num++;
}
int dfs(int u,int fa){
int lowu;
lowu=pre[u]=++dfst;
int v,e;
for(e=V[u];e!=-;e=E[e].next){
v=E[e].to;
if(!pre[v]){
int lowv=dfs(v,u);
lowu=min(lowu,lowv);
if(lowv>pre[u]&&!tag[E[e].num]){
ans++;
}
}
else if(v!=fa) lowu=min(lowu,pre[v]);
}
return lowu;
}
int main()
{
int n,m,Q;
int u,v;
int i,j=;
while(scanf("%d %d",&n,&m),n|m){
init(n);
for(i=;i<=m;i++){
scanf("%d %d",&u,&v);
tag[i]=;
add(u,v);
}
printf("Case %d:\n",j++);
scanf("%d",&Q); for(i=;i<=Q;i++) tag[i+m]=;
while(Q--){
scanf("%d %d",&u,&v);
add(u,v);
for(i=;i<=n;i++) pre[i]=;
ans=;
dfst=;
dfs(,);
printf("%d\n",ans);
}
printf("\n");
}
return ;
} // 在原来的基础上 执行一次dfs 然就找两点的lca 我不愿去缩点 啥的, 网上看到一个不错的,就用了
// 就是先让 x,y达到同一深度 然后回走 直到碰面 边上遇到桥就标记删除
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <string.h>
using namespace std;
#define MOD 1000000007
#define maxn 440000
#define maxm 100010
struct Edge{
int to;
// int num;
int next;
Edge(){};
Edge(int u,int v){to=u;next=v;}
}E[maxn];
int V[maxm],num;
bool tag[maxm];
int fa[maxm];
int pre[maxm],low;
int dfst;
int ans;
void init(int n){
dfst=;
num=;
ans=;
for(int i=;i<=n;i++){
V[i]=-;
pre[i]=;
tag[i]=;
}
}
void add(int u,int v){
E[num].to=v;
// E[num].num=m;
E[num].next=V[u];
V[u]=num++; E[num].to=u;
// E[num].num=m;
E[num].next=V[v];
V[v]=num++;
}
int dfs(int u,int dp){
int lowu=pre[u]=dp;
int v,e;
for(e=V[u];e!=-;e=E[e].next){
v=E[e].to;
if(!pre[v]){
fa[v]=u;
// printf("?%d %d %d\n",v,u,fa[v]);
int lowv=dfs(v,dp+);
lowu=min(lowu,lowv);
if(lowv>pre[u]){
ans++;
tag[v]=true; //printf("%d",v);
}
}
else if(v!=fa[u]) lowu=min(lowu,pre[v]);
}
// printf("%d %d ",u,fa[u]);
return lowu;
}
void lca(int x,int y){
if(pre[x]>pre[y]) swap(x,y);
while(pre[y]!=pre[x]){
if(tag[y]){ans--;tag[y]=false;}
y=fa[y];
}
while(x!=y){
if(tag[x]){ans--;tag[x]=false;}
if(tag[y]){ans--;tag[y]=false;}
x=fa[x];y=fa[y];
}
}
int main()
{
int n,m,Q;
int u,v;
int i,j=;
while(scanf("%d %d",&n,&m),n|m){
init(n);
for(i=;i<=m;i++){
scanf("%d %d",&u,&v);
add(u,v);
}
fa[]=;
dfs(,);
printf("Case %d:\n",j++);
scanf("%d",&Q);// for(i=1;i<=Q;i++) tag[i+m]=0;
while(Q--){
scanf("%d %d",&u,&v);
lca(u,v);
printf("%d\n",ans);
}
printf("\n");
}
return ;
}
 

poj 3694 Network的更多相关文章

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

    题目链接: Poj 3694 Network 题目描述: 给出一个无向连通图,加入一系列边指定的后,问还剩下多少个桥? 解题思路: 先求出图的双连通分支,然后缩点重新建图,加入一个指定的边后,求出这条 ...

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

    Network Time Limit:5000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Stat ...

  3. [双连通分量] POJ 3694 Network

    Network Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 9434   Accepted: 3511 Descripti ...

  4. poj 3694 Network 边双连通+LCA

    题目链接:http://poj.org/problem?id=3694 题意:n个点,m条边,给你一个连通图,然后有Q次操作,每次加入一条边(A,B),加入边后,问当前还有多少桥,输出桥的个数. 解题 ...

  5. POJ 3694 Network (tarjan + LCA)

    题目链接:http://poj.org/problem?id=3694 题意是给你一个无向图n个点,m条边,将m条边连接起来之后形成一个图,有Q个询问,问将u和v连接起来后图中还有多少个桥. 首先用t ...

  6. poj 3694 Network(双连通分量)

    题目:http://poj.org/problem?id=3694 #include <iostream> #include <cstring> #include <cs ...

  7. poj 3694 Network(割边+lca)

    题目链接:http://poj.org/problem?id=3694 题意:一个无向图中本来有若干条桥,有Q个操作,每次加一条边(u,v),每次操作后输出桥的数目. 分析:通常的做法是:先求出该无向 ...

  8. poj 3694 Network : o(n) tarjan + O(n) lca + O(m) 维护 总复杂度 O(m*q)

    /** problem: http://poj.org/problem?id=3694 问每加一条边后剩下多少桥 因为是无向图,所以使用tarjan缩点后会成一棵树并维护pre数组 在树上连一条边(a ...

  9. POJ 3694 Network (求桥,边双连通分支缩点,lca)

    Network Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 5619   Accepted: 1939 Descripti ...

  10. POJ 3694 Network(Tarjan求割边+LCA)

    Network Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 10969   Accepted: 4096 Descript ...

随机推荐

  1. 剑指offer--面试题15--相关

    感受:清晰的思路是最重要的!!! 题目:求链表中间节点 ListNode* MidNodeInList(ListNode* pHead) { if(pHead == NULL) return NULL ...

  2. uva 10887

    是个 hash  用的容器类水过 #include <iostream> #include <cstdio> #include <string> #include ...

  3. Unity3D 游戏开发构架篇 —— 动态大场景生成 = 区域加载+对象池管理

    项目做一个类似无尽模式的场景,想了一想,其实方法很简单,做一个相关的总结. 主要先谈一谈构架,后期附上代码. 一.区域加载 其实无尽场景的实现很简单,因为屏幕限制,那么不论何时何地,我们只能看到自己的 ...

  4. Unity3D–Texture图片空间和内存占用分析(转载)

    原地址:http://www.unity蛮牛.com/home.php?mod=space&uid=1801&do=blog&id=756 Texture图片空间和内存占用分析 ...

  5. 轻轻修改配置文件完成 OpenStack 监控

    当我们使用虚拟化云平台 OpenStack 时,必然要时时监控其虚拟机性能,随着近年企业级数据中心的不断发展,像混合虚拟化环境的业务需求也在持续增长中,因而也随之带来的监控需求更显重要,所以小编带来一 ...

  6. 常见的排序算法之Java代码解释

    一 简要介绍 一般排序均值的是将一个已经无序的序列数据重新排列成有序的 常见的排序分为: 1 插入类排序 主要就是对于一个已经有序的序列中,插入一个新的记录.它包括:直接插入排序,折半插入排序和希尔排 ...

  7. POJ2104 K-th Number Range Tree

    又是区间第k大,这次选择这道题是为以后写线段树套平衡树铺路的.Range Tree可以理解成线段树套vector吧,相当于每个结点多存了对应区间的一个排好序的序列.画一下就会知道空间的消耗是nlogn ...

  8. JsRender系列demo(3)-自定义容器

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  9. HDU 4143 A Simple Problem(枚举)

    题目链接 题意 : 就是给你一个数n,让你输出能够满足y^2 = n +x^2这个等式的最小的x值. 思路 : 这个题大一的时候做过,但是不会,后来学长给讲了,然后昨天比赛的时候二师兄看了之后就敲了, ...

  10. 李洪强iOS开发之OC语言@property @synthesize和id

    OC语言@property @synthesize和id 一.@property @synthesize关键字 注意:这两个关键字是编译器特性,让xcode可以自动生成getter和setter的声明 ...