zoukankan      html  css  js  c++  java
  • FZU2259 : 图

    假设删除的边是$(u,v)$,分两种情况讨论:

    $1.$删除$(u,v)$之后$(u,v)$不再连通,那么说明$(u,v)$是图的桥,同时整个图都要是二分图。

    $2.$删除$(u,v)$之后$(u,v)$依然连通,那么图不能是二分图,但是删除$(u,v)$之后必须要是二分图,这说明$(u,v)$位于所有奇环的交上,在忽略这条边之后可以进行黑白染色,且$u,v$必定同色。对图求出dfs生成树,找出所有基环,对每条边标记它被多少个奇数长度的基环与多少个偶数长度的基环经过。如果一条边被所有奇数长度的基环经过,且不被任何一个偶数长度的基环经过,那么就可行。

    时间复杂度$O(n+m)$。

    #include<cstdio>
    const int N=200010;
    int n,m,i,x,y,dep[N],g[N],v[N<<1],w[N<<1],nxt[N<<1],ed,d[N],dfn,f[N];
    int cnt,loop,tag0[N],tag1[N],h0[N],h1[N],ans;
    inline void add(int x,int y,int z){v[++ed]=y;w[ed]=z;nxt[ed]=g[x];g[x]=ed;}
    void dfs(int x){
      d[x]=++dfn;
      for(int i=g[x];i;i=nxt[i])if(w[i]!=f[x]){
        int y=v[i];
        if(d[y]&&d[y]<=d[x]){
          if(dep[x]^dep[y]){
            tag0[y]--;
            tag0[x]++;
            h0[w[i]]=1;
          }else{
            if(x==y)loop++;else cnt++;
            tag1[y]--;
            tag1[x]++;
            h1[w[i]]=1;
          }
        }else if(!d[y])f[y]=w[i],dep[y]=dep[x]^1,dfs(y);
      }
    }
    void cal(int x){
      for(int i=g[x];i;i=nxt[i])if(f[v[i]]==w[i]&&d[v[i]]>d[x])cal(v[i]),tag0[x]+=tag0[v[i]],tag1[x]+=tag1[v[i]];
      h0[f[x]]=tag0[x],h1[f[x]]=tag1[x];
    }
    namespace BCC{
    int cut[N],g[N],v[N<<1],nxt[N<<1],ed;
    int f[N],dfn[N],low[N],num;
    inline void add(int x,int y){v[++ed]=y;nxt[ed]=g[x];g[x]=ed;}
    void tarjan(int x){
      dfn[x]=low[x]=++num;
      for(int i=g[x];i;i=nxt[i])if(!dfn[v[i]]){
        f[v[i]]=i>>1,tarjan(v[i]);
        if(low[x]>low[v[i]])low[x]=low[v[i]];
      }else if(f[x]!=(i>>1)&&low[x]>dfn[v[i]])low[x]=dfn[v[i]];
      if(f[x]&&low[x]==dfn[x])cut[f[x]]=1;
    }
    }
    int main(){
      while(~scanf("%d%d",&n,&m)){
        for(BCC::ed=i=1;i<=m;i++){
          scanf("%d%d",&x,&y);
          add(x,y,i),add(y,x,i);
          BCC::add(x,y),BCC::add(y,x);
        }
        for(i=1;i<=n;i++)if(!d[i])dfs(i),cal(i);
        cnt+=loop/2;
        if(!cnt){
          for(i=1;i<=n;i++)if(!BCC::dfn[i])BCC::tarjan(i);
          for(i=1;i<=m;i++)if(BCC::cut[i])ans++;
        }else{
          for(i=1;i<=m;i++)if(h1[i]==cnt&&!h0[i])ans++;
        }
        printf("%d
    ",ans);
        ed=dfn=cnt=loop=ans=0;
        for(i=0;i<=n;i++)dep[i]=g[i]=d[i]=f[i]=tag0[i]=tag1[i]=0;
        for(i=0;i<=m;i++)h0[i]=h1[i]=0;
        for(i=0;i<=m;i++)BCC::cut[i]=0;
        for(i=0;i<=n;i++)BCC::g[i]=BCC::f[i]=BCC::dfn[i]=BCC::low[i]=0;
        BCC::num=0;
      }
    }
    

      

  • 相关阅读:
    SpringMVC从Request域中获取数据
    SpringMVC重定向
    SpringMVC的请求转发的三种方法
    SpringMVC文件上传
    SpringMVC处理请求释放静态资源的三种方式
    jackson实现json转换
    SpringMVC之请求部分
    SpringMVC的执行流程
    Java [Leetcode 39]Combination Sum
    深入解析Java对象的hashCode和hashCode在HashMap的底层数据结构的应用
  • 原文地址:https://www.cnblogs.com/clrs97/p/7182408.html
Copyright © 2011-2022 走看看