[HDU2460]Network

Posted youddjxd

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[HDU2460]Network相关的知识,希望对你有一定的参考价值。

Network

题目大意

给你一个无向连通图,再给出一些添边操作,询问每次添边操作之后图中还剩下多少桥。

Solution

其实很水,缩个点,然后此时图是一棵树,其中每条边都是割边,然后每次加边就把左右端点路径上的所有边都变成非割边即可

树剖维护一下。放这个题的原因就是码量大了一点。

upd:有一个码量很小的生成树的做法。。。我哭了

code:

#include<bits/stdc++.h>
using namespace std;
struct qwq
    int v;
    int nxt;
edge[400010];
int cnt=-1;
int head[200010];
void add(int u,int v)
    edge[++cnt].nxt=head[u];
    edge[cnt].v=v;
    head[u]=cnt;

struct tarj
    int ind;
    int dfn[200010];
    int low[200010];
    int col[200010];
    bool vis[200010];
    int stk[200010];
    int top;
    int tot;
    int x[200010],y[200010];
    void init()
        ind=0;
        tot=0;
        top=0;
        memset(low,0,sizeof(low));
        memset(dfn,0,sizeof(dfn));
        memset(col,0,sizeof(col));
        memset(vis,0,sizeof(vis));
    
    void tarjan(int u,int fa)
        dfn[u]=low[u]=++ind;
        stk[++top]=u;
        vis[u]=true;
        for(int i=head[u];~i;i=edge[i].nxt)
            int v=edge[i].v;
            if(v==fa)continue;
            if(vis[v])
                low[u]=min(low[u],dfn[v]);
            
            else if(!dfn[v])
                tarjan(v,u);
                low[u]=min(low[u],low[v]);
            
        
        if(dfn[u]==low[u])
            tot++;
            int v;
            do
                v=stk[top];
                top--;
                col[v]=tot;
            while(u!=v);
        
    
a;
int siz[200010];
int top[200010];
int son[200010];
int fa[200010];
int tid[200010];
int dep[200010];
void dfs1(int u,int fath,int depth)
    fa[u]=fath;
    dep[u]=depth;
    siz[u]=1;
    for(int i=head[u];~i;i=edge[i].nxt)
        int v=edge[i].v;
        if(v==fath)continue;
        dfs1(v,u,depth+1);
        siz[u]+=siz[v];
        if(!son[u]||siz[v]>siz[son[u]])son[u]=v;
    

int tim;
void dfs2(int u,int topf)
    top[u]=topf;
    tid[u]=++tim;
    if(son[u])dfs2(son[u],topf);
    for(int i=head[u];~i;i=edge[i].nxt)
        int v=edge[i].v;
        if(v==fa[u]||v==son[u])continue;
        dfs2(v,v);
    

int sum[400010];
int tag[400010];
void build(int o,int l,int r)
    tag[o]=0;
    if(l==r)
        sum[o]=1;
        return;
    
    int mid=(l+r)/2;
    build(o*2,l,mid);
    build(o*2+1,mid+1,r);
    sum[o]=sum[o*2]+sum[o*2+1];

void pushdown(int o)
    if(tag[o])
        sum[o*2]=sum[o*2+1]=0;
        tag[o*2]=tag[o*2+1]=1;
        tag[o]=0;
    

void update(int o,int l,int r,int L,int R)
    if(L>R)return;
    if(L<=l&&r<=R)
        tag[o]=1,sum[o]=0;
        return;
    
    pushdown(o);
    int mid=(l+r)/2;
    if(L<=mid)update(o*2,l,mid,L,R);
    if(mid<R)update(o*2+1,mid+1,r,L,R);
    sum[o]=sum[o*2]+sum[o*2+1];

int query(int o,int l,int r,int L,int R)
    if(L>R)return 0;
    if(L<=l&&r<=R)
        return sum[o];
    
    pushdown(o);
    int mid=(l+r)/2;
    int ret=0;
    if(L<=mid)ret+=query(o*2,l,mid,L,R);
    if(mid<R)ret+query(o*2+1,mid+1,r,L,R);
    return ret;

void updatetree(int x,int y)
    while(top[x]!=top[y])
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        update(1,1,a.tot,tid[top[x]],tid[x]);
        x=fa[top[x]];
    
    if(dep[x]>dep[y])swap(x,y);
    update(1,1,a.tot,tid[x]+1,tid[y]);

int main()
    memset(head,-1,sizeof(head));
    int n,m;
    int cas=0;
    while(scanf("%d%d",&n,&m)&&n&&m)
        printf("Case %d:\n",++cas);
        a.init();
        tim=0;
        memset(siz,0,sizeof(siz));
        memset(top,0,sizeof(top));
        memset(son,0,sizeof(son));
        memset(fa,0,sizeof(fa));
        memset(tid,0,sizeof(tid));
        memset(dep,0,sizeof(dep));
        memset(head,-1,sizeof(head));
        cnt=-1;
        for(int i=1;i<=m;++i)
            int u,v;
            scanf("%d%d",&u,&v);
            add(u,v),add(v,u);
            a.x[i]=u,a.y[i]=v;
        
        for(int i=1;i<=n;++i)
            if(!a.vis[i])a.tarjan(i,-1);
        
        memset(head,-1,sizeof(head));
        cnt=-1;
        for(int i=1;i<=m;++i)
            if(a.col[a.x[i]]!=a.col[a.y[i]])
                add(a.col[a.x[i]],a.col[a.y[i]]);
                add(a.col[a.y[i]],a.col[a.x[i]]);
            
        
        dfs1(1,0,1);
        dfs2(1,1);
        build(1,1,a.tot);
        int q;
        scanf("%d",&q);
        for(int i=1;i<=q;++i)
            int u,v;
            scanf("%d%d",&u,&v);
            updatetree(a.col[u],a.col[v]);
            printf("%d\n",sum[1]-1);
        
        puts("");
       

以上是关于[HDU2460]Network的主要内容,如果未能解决你的问题,请参考以下文章

hdu 4520

bzoj2460 BeiJing2011—元素

BZOJ 2460: [BeiJing2011]元素

BZOJ 2460 Beijing2011 元素

bzoj2460[BeiJing2011]元素

[BZOJ2460][BeiJing2011]元素