二分图的一个重要性质

一个图如果是二分图,那么这个图不存在奇环,反之也成立

模板题目:Catch

题意:一个无向图有\(n\)个节点,\(m\)条边,从编号为\(s\)的点出发,每个单位时间可以从当前点走到一个相邻的点,问存不存在这样一个时刻,从\(s\)出发,可以在这个时刻到达任何一个点。

题解我们称那个符合要求的时刻为:完美时刻.首先如果这个无向图是不连通,就不存在完美时刻. 当无向图连通的时候,如果该图是二分图,依然不存在完美时刻。因为整个图被分为两半,一半是奇数时刻能到的,另一半是偶数时刻能到的。

综上所述,只有在图连通且非二分图的时候,才能保证有完美时刻存在.我们只需要判断图是否连通且非二分图即可.其中图是否连通可以直接通过从起点S对图节点染色后,看看是否还有未染色的节点来得出.(错误,不可通过二分图递归判断,因为如果颜色冲突了就立即返回,其他点都没有染色). 连通必须通过并查集判断.

AC_Code:

 1 #include <iostream>
 2 #include <cstring>
 3 #include <string>
 4 #include <vector>
 5 using namespace std;
 6 typedef long long ll;
 7 #define endl '\n'
 8 const int mod=998244353;
 9 const int maxn=1e5+10;
10 const int maxm=5e5+10;
11 
12 int n,m,s;
13 vector<int>G[maxn];
14 int color[maxn];
15 int fa[maxn];
16 bool flag;
17 
18 int find_fa(int i){
19     if( fa[i]==i ) return i;
20     return fa[i]=find_fa(fa[i]);
21 }
22 
23 void init(){
24     for(int i=0;i<n;i++){
25         G[i].clear();
26         fa[i]=i;
27     }
28     memset(color,0,sizeof(color));
29     flag=true;
30 }
31 
32 bool dfs(int u,int c){
33     color[u]=c;
34     for(size_t i=0;i<G[u].size();i++){
35         int to=G[u][i];
36         if( !flag ) return false;
37         else if( !color[to] ){
38             dfs(to,3-c);
39         }else if( color[to]==c ){
40             return flag=false;
41         }
42     }
43     return true;
44 }
45 
46 int main()
47 {
48     int t,cas=0; scanf("%d",&t);
49     while( t-- ){
50         scanf("%d%d%d",&n,&m,&s);
51         init();
52         while( m-- ){
53             int u,v; scanf("%d%d",&u,&v);
54             G[u].push_back(v);
55             G[v].push_back(u);
56             u=find_fa(u);
57             v=find_fa(v);
58             if( u!=v ) fa[u]=v;
59         }
60         int cnt=0;//连通分量个数
61         for(int i=0;i<n;i++){
62             if( find_fa(i)==i )
63                 cnt++;
64         }
65         if( cnt>1 ){
66             printf("Case %d: NO\n",++cas);
67             continue;
68         }
69         if( !dfs(s,1) ) printf("Case %d: YES\n",++cas);//如果不是二分图则存在这么一个时刻
70         else printf("Case %d: NO\n",++cas);//否则不存在
71     }
72     return 0;
73 }

大佬博客:here

posted @ 2020-08-10 18:08  swsyya  阅读(161)  评论(0编辑  收藏  举报

回到顶部