zoukankan      html  css  js  c++  java
  • Network(poj 3694)

    题意:一个无向图可以有重边,下面q个操作,每次在两个点间连接一条有向边,每次连接后整个无向图还剩下多少桥(注意是要考虑之前连了的边,每次回答是在上一次的基础之上)

    /*
      tarjan+LCA
      先用tarjan缩点,那么这个图就会变成一棵树,当我们连起不在同一节点时,就相当于
      把树上的两个节点连了起来,这两个节点同他们的公共祖先会形成一个新的缩点,每次统计
      桥的个数。 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define M 200010
    using namespace std;
    int n,m,num,head[M],low[M],dfn[M],topt;
    int s[M],top,f[M],sum,belong[M],cnt,cas;
    int Num,Head[M],fa[M],c[M],vis[M];
    struct node{int v,pre;}e[M*2];
    struct Node{int v,pre;}E[M*2];
    void Add(int from,int to)
    {
        e[num].v=to;
        e[num].pre=head[from];
        head[from]=num++;
    }
    void add(int from,int to)
    {
        E[Num].v=to;
        E[Num].pre=Head[from];
        Head[from]=Num++;
    }
    void Tarjan(int x,int fa)
    {
        low[x]=dfn[x]=++topt;
        s[++top]=x;f[x]=1;
        for(int i=head[x];i!=-1;i=e[i].pre)
        {
            int v=e[i].v;
            if(i==(fa^1))continue;
            if(dfn[v]==0)
            {
                Tarjan(v,i);low[x]=min(low[x],low[v]);
            }
            else if(f[v])low[x]=min(low[x],dfn[v]);
        }
        if(low[x]==dfn[x])
        {
            sum++;
            while(x!=s[top])
            {
                f[s[top]]=0;belong[s[top]]=sum;top--;
            }
            f[s[top]]=0;belong[s[top]]=sum;top--;
        }
    }
    void Dfs(int now,int from,int dep)
    {
        fa[now]=from;c[now]=dep;
        for(int i=Head[now];i!=-1;i=E[i].pre)
          if(E[i].v!=from)
            Dfs(E[i].v,now,dep+1);
    }
    void LCA(int a,int b)
    {
        if(c[a]<c[b])swap(a,b);
        int t=c[a]-c[b];
        for(int i=1;i<=t;i++)
        {
            if(vis[a]==0)cnt--;
            vis[a]=1;a=fa[a];
        }
        while(a!=b)
        {
            if(vis[a]==0)cnt--;
            vis[a]=1;a=fa[a];
            if(vis[b]==0)cnt--;
            vis[b]=1;b=fa[b];
        }
    }
    int main()
    {
        while(1)
        {
            scanf("%d%d",&n,&m);
            if(n==0&&m==0)break;
            memset(head,-1,sizeof(head));
            memset(Head,-1,sizeof(Head));
            memset(low,0,sizeof(low));
            memset(dfn,0,sizeof(dfn));
            memset(f,0,sizeof(f));
            memset(belong,0,sizeof(belong));
            memset(vis,0,sizeof(vis));
            memset(c,0,sizeof(c));
            memset(fa,0,sizeof(fa));
            memset(s,0,sizeof(s));
            Num=num=topt=sum=0;
            int u,v;
            for(int i=1;i<=m;i++)
            {
                scanf("%d%d",&u,&v);
                Add(u,v);Add(v,u);
            }
            for(int i=1;i<=n;i++)
              if(dfn[i]==0)
                Tarjan(i,-1);
            for(int u=1;u<=n;u++)
              for(int i=head[u];i!=-1;i=e[i].pre)
                if(belong[u]!=belong[e[i].v])
                  add(belong[u],belong[e[i].v]);
            Dfs(1,1,0);cnt=sum-1;
            scanf("%d",&m);
            printf("Case %d:
    ",++cas);
            for(int i=1;i<=m;i++)
            {
                scanf("%d%d",&u,&v);
                int U=belong[u];
                int V=belong[v];
                if(U==V)
                {
                    printf("%d
    ",cnt);continue;
                }
                LCA(U,V);
                printf("%d
    ",cnt);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    ueditor 后端配置项没有正常加载,上传插件不能正常使用 UTF8 PHP
    dedecms 后台栏目全部展开 包括三级栏目
    修改DedeCMS图片上传路径命名规则的具体方法步骤
    dedecms织梦副栏目名称和链接调用
    当位于顶级栏目显示下级栏目,当位于二级栏目显示同级栏目,当位于三级目录,显示上级栏目
    织梦多个栏目arclist调用副栏目不显示的解决办法
    PL/SQL连接64位Oracle配置方法
    U盘分区之后如何恢复
    Myeclipse 的使用随笔
    eclipse和myeclipse的差别问题
  • 原文地址:https://www.cnblogs.com/harden/p/5802042.html
Copyright © 2011-2022 走看看