POJ3694 Network 割边+LCA

原创 2015年07月06日 19:46:23

题目链接:

Poj3694



题意:

给出一个N(1 ≤ N ≤ 100,000)个点 和 M(N - 1 ≤ M ≤ 200,000)的连通图.

有Q ( 1 ≤ Q ≤ 1,000)个询问 每次询问增加一条边(累加下去)

输出每增加一条边后剩下的桥的数量




题解:

10W点加1000次询问 每次询问都用Tarjin算法求一次肯定会超时的

考虑  每次加一条边a-b的实质:

从a到b的路径中的所有割边都将消失

那如何记录这条路径呢

在Tarjan算法递归的过程中通过树边建立一棵树 

然后每次询问分别从a  b开始 一直到它们的最近公共祖先 出现的割边全部消失即可


代码:


#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#define maxn 100050
using namespace std;
struct node{
    int to,next;
}edge[maxn*4];
int head[maxn];
int s;

int dfn[maxn],low[maxn],num;

int level[maxn],fa[maxn];
int flag[maxn];
int n,ans;
void init()
{
    memset(head,-1,sizeof(head));
    memset(dfn,0,sizeof(dfn));
    memset(flag,0,sizeof(flag));
    s=ans=num=0;
    level[0]=0;
    for(int i=1;i<=n;i++)
        fa[i]=i;
}

void addedge(int a,int b)
{
    edge[s]={b,head[a]};
    head[a]=s++;
}

void lca(int a,int b)
{
    while(level[b]>level[a])
    {
        if(flag[b])
            ans--,flag[b]=0;
        b=fa[b];
    }
    while(level[a]>level[b])
    {
        if(flag[a])
            ans--,flag[a]=0;
        a=fa[a];
    }
    while(a!=b)
    {
        if(flag[a])
            ans--,flag[a]=0;
        if(flag[b])
            ans--,flag[b]=0;
        a=fa[a],b=fa[b];
    }
}

void Tarjan(int u,int pre)
{
    dfn[u]=low[u]=++num;
    level[u]=level[pre]+1;              //建树
    for(int i=head[u];i!=-1;i=edge[i].next)
    {
        int v=edge[i].to;
        if(!dfn[v])
        {
            fa[v]=u;
            Tarjan(v,u);
            low[u]=min(low[u],low[v]);
            if(dfn[u]<low[v])         //标记割边
                flag[v]=1,ans++;
        }
        if(v!=pre)
            low[u]=min(low[u],dfn[v]);
    }
}

int main()
{
    int m,a,b;
    int Case=1;
    while(scanf("%d%d",&n,&m)&&(n+m))
    {
        init();
        while(m--)
        {
            scanf("%d%d",&a,&b);
            addedge(a,b);
            addedge(b,a);
        }
        Tarjan(1,0);
        scanf("%d",&m);
        printf("Case %d:\n",Case++);
        while(m--)
        {
            scanf("%d%d",&a,&b);
            if(ans!=0)
                lca(a,b);
            printf("%d\n",ans);
        }
        printf("\n");
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Network-POJ3694并查集+LCA

Network Time Limit: 5000MS   Memory Limit: 65536K       Description A network administra...

【POJ 3694】 Network(割边<桥>+LCA)

【POJ 3694】 Network(割边+LCA) Network Time Limit: 5000MS   Memory Limit: 65536K ...

POJ 3694 Network 割边+LCA

这道题跟3177意思差不多,不过最后问的不一样,说是加入某条边后,问图内剩余的桥有多少。 这题的大概思路就是,先求割边并标记,然后缩点,形成一棵树,然后把这颗树上各个结点的父结点用dfs求出来,再然...

POJ 3694 Network

题目大意: 给一个连通图G,问加入某一条边后图中还有多少割边。 解题思路: 1、用Tarjan算法求出所有的割边和每一个点的父节点,并记录。记录每一个节点的父节点可以形成一棵深搜树。 ...

POJ 3694 强连通分量+LCA

点击打开链接 题意:给一个图,然后依次加进去边,问每次加过边后还有几个桥,之前加入的会影响后面加入的 思路:先将图的桥全部找出来,然后将桥的点标记上,然后不需要缩点,直接进行裸的LCA,再找最近公...
  • Dan__ge
  • Dan__ge
  • 2016年05月11日 08:25
  • 921

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

http://poj.org/problem?id=3694 Network Time Limit: 5000MS   Memory Limit: 65536K Total Submi...

POJ3694 Network 无向图的桥

题目描述:Description A network administrator manages a large network. The network consists of N compute...

POJ3694-Network(LCA+边联通分量+桥)

Network Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 9714   Accepted: 3603 ...

poj3694 Network

给你一张连通无向图,向图中加Q次边,问你每次加边后,图中有几条割边。是可以有重边的,比如原图中边(1,2)是一条割边,再加一条边(1,2) ,就消除掉了一条割边。 但是这个题有点别扭,加边的时候会有...

POJ 3694 Network(Tarjan求割边+LCA)

题目源: POJ3694 Network 题意:给你一个图,有Q个操作,每个操作将点u和v之间连一条边,问你在每次加边之后图中的割边的数量。 分析:首先用Tarjan在加边前求一次割边的数量,并用...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:POJ3694 Network 割边+LCA
举报原因:
原因补充:

(最多只允许输入30个字)