zoukankan      html  css  js  c++  java
  • 【判断二分图】C. Catch

    https://www.bnuoj.com/v3/contest_show.php?cid=9154#problem/C

    【题意】

    • 给定一个无向图,给定小偷的起始位置
    • 从这个起始位置开始,小偷可以在单位时间内逃到相邻的点
    • 问是否存在某一时刻,小偷可能到达这个无向图的任意点

    【思路】

    • 首先这个无向图必须是连通的
    • 如果小偷能够在某一奇数步到达某一点,那么他可以在任意奇数步到达这一点;偶数步同理
    • 如果这个图是一个二分图(即奇数步到达的点在一个集合,偶数步到达的点在一个集合),那么对于任意时刻(不是奇数步就是偶数步),小偷不可能到达这个图的任意点(只能是所有的奇数点或偶数点)
    • 如果这个图不是二分图(等价于图中存在一个奇环),则我们可以找到一个点可以在奇数步到达,也可以在偶数步到达;进一步,以这个点为出发点,其他的所有点也都可以染相反的颜色。即只要图中有一个奇环,这个图的任意点就是可以是0,也可以是1。
    • 某一时刻,小偷可能到达这个无向图的任意点等价于这个图连通且不是二分图。

    【Accepted】

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<string>
      5 #include<cmath>
      6 #include<algorithm>
      7 #include<queue>
      8 using namespace std;
      9 const int maxn=1e5+3;
     10 const int maxm=5e5+3;
     11 int n,m,s;
     12 struct edge
     13 {
     14     int to;
     15     int nxt;
     16 }e[maxm];
     17 int tot;
     18 int head[maxn];
     19 int col[maxn];
     20 bool vis[maxn];
     21 void init()
     22 {
     23     tot=0;
     24     memset(head,-1,sizeof(head));
     25     memset(vis,false,sizeof(vis));
     26     memset(col,0,sizeof(col));
     27 }
     28 void add(int u,int v)
     29 {
     30     e[tot].to=v;
     31     e[tot].nxt=head[u];
     32     head[u]=tot++;
     33 }
     34 
     35 bool BFS(int u)
     36 {
     37     int cnt=0;
     38     queue<int> Q;
     39     Q.push(u);
     40     vis[u]=true;
     41     cnt++;
     42     while(!Q.empty())
     43     {
     44         u=Q.front();
     45         Q.pop();
     46         for(int i=head[u];i!=-1;i=e[i].nxt)
     47         {
     48             int v=e[i].to;
     49             if(!vis[v])
     50             {
     51                 vis[v]=true;
     52                 cnt++;
     53                 Q.push(v);                
     54             }
     55          } 
     56     }
     57     if(cnt==n)
     58     {
     59         return true;
     60     }
     61     else
     62     {
     63         return false;    
     64     }
     65 }
     66 bool Color(int u)
     67 {
     68     queue<int> Q;
     69     Q.push(s);
     70     while(!Q.empty())
     71     {
     72         u=Q.front();
     73         Q.pop();
     74         for(int i=head[u];i!=-1;i=e[i].nxt)
     75         {
     76             int v=e[i].to;
     77             if(!col[v])
     78             {
     79                 col[v]=!col[u];
     80                 Q.push(v);
     81             }
     82             else if(col[v]==col[u])
     83             {
     84                 return false;
     85             }
     86         }
     87      } 
     88      return true;
     89 }
     90 int main()
     91 {
     92     int cas=0;
     93     int T;
     94     scanf("%d",&T);
     95     while(T--)
     96     {
     97         init();
     98         scanf("%d%d%d",&n,&m,&s);
     99         while(m--)
    100         {
    101             int u,v;
    102             scanf("%d%d",&u,&v);
    103             add(u,v);
    104             add(v,u);
    105         }
    106         if(BFS(s)&&!Color(s))
    107         {
    108             printf("Case %d: YES
    ",++cas);
    109         }
    110         else
    111         {
    112             printf("Case %d: NO
    ",++cas);
    113         }
    114     }
    115     return 0;
    116 }
    View Code
  • 相关阅读:
    了解 DICOM 基本协议与其相关
    C# PropertyInfo 反射实体部分字段
    ref(引用参数) 和 out(输出参数) 区别
    Linq Where Expression<Func<T,bool>> 查询条件
    随笔规范
    C# 集合分析
    C# 几种常用的数据类型
    关于 C# 方法参数的理解
    打算开始写博客了
    有趣的算法、逻辑面试题
  • 原文地址:https://www.cnblogs.com/itcsl/p/7190937.html
Copyright © 2011-2022 走看看