二分图染色判断

二分图染色判断

判断图中不存在奇数环

O(n+m)

//P1155
# include <bits/stdc++.h>
using namespace std;

const int MAXN=1e3+100;
vector<int> G[MAXN];
int color[MAXN];
int bipart(int u)
{
   int len=G[u].size();
   for(int i=0;i<len;++i){
       int v=G[u][i];
       if(color[v]==color[u]) return 0;
       if(!color[v]){
           color[v]=3-color[u];
           if(!bipart(v)) return 0;
      }
  }
   return 1;
}
int a[MAXN],f[MAXN];
stack<int> s1,s2;
int main()
{
   int N; scanf("%d",&N);
   for(int i=1;i<=N;++i){
       scanf("%d",&a[i]);
       f[i]=a[i];
  }
   for(int i=N-1;i>=1;i--){
       f[i]=min(f[i],f[i+1]);
  }
   for(int i=1;i<N;++i){
       for(int j=i+1;j<N;++j){
           if(a[i]<a[j]&&f[j+1]<a[i]){
               G[a[i]].push_back(a[j]);
               G[a[j]].push_back(a[i]);
          }
      }
  }
   for(int i=1;i<=N;++i){
       if(!color[a[i]]){
           color[a[i]]=1;
           if(!bipart(a[i])){
               printf("0\n");
               return 0;
          }
      }
  }
   int now=1;
   for(int i=1;i<=N;++i){
       if(color[a[i]]==1){
           s1.push(a[i]);
           printf("a ");
      }else{
           s2.push(a[i]);
           printf("c ");
      }
       while((!s1.empty()&&s1.top()==now)||(!s2.empty()&&s2.top()==now)){
           if((!s1.empty())&&(s1.top()==now)){
               printf("b ");
               s1.pop();
               now++;
          }
           if((!s2.empty())&&(s2.top()==now)){
               printf("d ");
               s2.pop();
               now++;
          }
      }
  }
   return 0;
}

eg1:圆桌骑士

注意:如果是判断一个连通分量是不是二分图,要用queue把连通分量里面的点一个个加入判断

# include <bits/stdc++.h>
using namespace std;

typedef long long LL;
const int MAXN=1e3+100;
struct Edge{
   int u,v;
};
int dfn[MAXN],iscut[MAXN],bccno[MAXN],dfs_clock,bcc_cnt;
vector<int> G[MAXN],bcc[MAXN];
stack<Edge> S;
int dfs(int u,int fa)
{
   int lowu=dfn[u]=++dfs_clock;
   int child=0;
   int len=G[u].size();
   for(int i=0;i<len;++i){
       int v=G[u][i];
       Edge e=(Edge){u,v};
       if(!dfn[v]){
           S.push(e);
           child++;
           int lowv=dfs(v,u);
           lowu=min(lowu,lowv);
           if(lowv>=dfn[u]){
               iscut[u]=1;
               bcc_cnt++;
               for(;;){
                   Edge x=S.top(); S.pop();
                   if(bccno[x.u]!=bcc_cnt) { bcc[bcc_cnt].push_back(x.u); bccno[x.u]=bcc_cnt;}
                   if(bccno[x.v]!=bcc_cnt) { bcc[bcc_cnt].push_back(x.v); bccno[x.v]=bcc_cnt;}
                   if(x.u==u&&x.v==v) break;
              }
          }
      }else if(dfn[v]<dfn[u]&&v!=fa){
           S.push(e); lowu=min(dfn[v],lowu);
      }
  }
   if(fa<0&&child==1) iscut[u]=0;
   return lowu;
}
void find_bcc(int n)
{
   memset(dfn,0,sizeof(dfn));
   memset(iscut,0,sizeof(iscut));
   memset(bccno,0,sizeof(bccno));
   dfs_clock=bcc_cnt=0;
   for(int i=1;i<=n;++i){
       if(!dfn[i]) dfs(i,-1);
  }
}

int mp[MAXN][MAXN],odd[MAXN],color[MAXN];
void init(int n)
{
   for(int i=0;i<=2*n;++i){
       G[i].clear();
       bcc[i].clear();
       odd[i]=0;
       for(int j=0;j<2*n;++j){
           mp[i][j]=0;
      }
  }
}
//v-DCC

int bipart(vector<int> &V)
{
   memset(color,0,sizeof(color));
   int LEN=V.size();
   queue<int> q;
   q.push(V[0]);
   color[V[0]]=1;
   while(!q.empty()){
       int u=q.front(); q.pop();
       int len=G[u].size();
       for(int i=0;i<len;++i){
           int v=G[u][i];
           int flag=0;
           for(int j=0;j<LEN;++j){
               if(V[j]==v){
                   flag=1;
                   break;
              }
          }
           if(!flag) continue;
           if(color[u]==color[v]) return 0;
           if(!color[v]){
               color[v]=3-color[u];
               q.push(v);
          }
      }
  }
   return 1;
}
int main()
{
   int N,M;
   while(~scanf("%d%d",&N,&M))
  {
       if(N==0&&M==0) break;
       init(N);
       for(int i=1;i<=M;++i){
           int u,v; scanf("%d%d",&u,&v);
           mp[u][v]=1,mp[v][u]=1;
      }
       for(int i=1;i<=N;++i){
           for(int j=i+1;j<=N;++j){
               if(!mp[i][j]){
                   G[i].push_back(j);
                   G[j].push_back(i);
              }
          }
      }
       find_bcc(N);

       for(int i=1;i<=bcc_cnt;++i){
           int len=bcc[i].size();
           if(len>2&&!bipart(bcc[i])){
               for(int j=0;j<len;++j){
                   odd[bcc[i][j]]=1;
              }
          }
      }
       LL ans=0;
       for(int i=1;i<=N;++i){
           if(!odd[i]) ans++;
      }
       printf("%lld\n",ans);
  }

   return 0;
}
/*
9
1 3
4 1
3 5
1 2
2 6
1 5
6 3
1 6
3 2
6
1 2
1 3
2 4
2 5
3 6
3 7
*/



posted @   fengzlj  阅读(174)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示