• [转载]HDU 3478 判断奇环


    题意:给定n个点,m条边的无向图(没有重边和子环)。从给定点出发,每个时间走到相邻的点,可以走重复的边,相邻时间不能停留在同一点,判断是否存在某个时间停留在任意的n个点。

    分析:

    (1)首先,和出发点的位置没有关系。因为可以走重复的边,且时间没有限制大小。

    (2)图必须是联通的

    (3)

    1)图为:2-0-1-3

    从0点出发(时间为0),一个时间后到达1或2(时间为1),再一个时间后到达0或3(时间为2)。。。

    可以发现,点分为两类,奇数时间到达和偶数时间到达,答案为NO

    2)图为:2-0-1-2(奇环)

    · 此图中的点,即可以在奇数时间到达,又可以在偶数时间到达。则答案为YES。比如都有个偶数的到达时间,在小时间在往返的走重复边后,(不改变奇偶,只改变大小,+2)

    3)图为:2-0-1-3-2(偶环)

    此图中的点和1)类似,同样分为两类。答案为NO

    综上:所有点必须都能在奇数时间和偶数时间到达,则需要图能够改变到达点时间奇偶的结构。

    由上可知,图中必须存在奇环。问题变成了,判断图是否存在奇环和是否连通。

     1 //#pragma warning (disable: 4786)
     2 //#pragma comment (linker, "/STACK:16777216")
     3 //HEAD
     4 #include <cstdio>
     5 #include <ctime>
     6 #include <cstdlib>
     7 #include <cstring>
     8 #include <queue>
     9 #include <string>
    10 #include <set>
    11 #include <stack>
    12 #include <map>
    13 #include <cmath>
    14 #include <vector>
    15 #include <iostream>
    16 #include <algorithm>
    17 using namespace std;
    18 
    19 typedef long long LL;
    20 const int INF = 1000000007;
    21 const double eps = 1e-10;
    22 const int maxn = 100010;
    23 const int MOD = 9997;
    24 
    25 int n;
    26 int m, st;
    27 int tot;
    28 vector<int>adj[maxn];
    29 int vis[maxn];
    30 int fla;
    31 
    32 int dfs(int x, int fa, int val)
    33 {
    34     if (vis[x] == -1) vis[x] = val;
    35     else return vis[x];
    36     tot++;
    37 
    38     for (int i = 0; i < adj[x].size(); i++)
    39     {
    40         int y = adj[x][i];
    41         //if (y != fa)
    42         //{
    43             if (vis[x] == dfs(y, x, vis[x] ^ 1))
    44                 fla = 1;
    45         //}
    46     }
    47     return vis[x];
    48 }
    49 
    50 int main ()
    51 {
    52     int T;
    53     cin >> T;
    54     int x, y;
    55     int ncase = 1;
    56     while (T--)
    57     {
    58         memset(vis, -1, sizeof(vis));///初始化为-1,染成0和1
    59         cin >> n >> m >> st;
    60         for (int i = 0; i< n; i++) adj[i].clear();
    61         while (m--)
    62         {
    63             scanf("%d%d", &x,&y);
    64             adj[x].push_back(y);
    65             adj[y].push_back(x);
    66         }
    67         fla = 0;///判断是否找到奇环
    68         tot = 0;///记录联通的点数
    69         dfs(st, -1, 0);
    70 
    71         printf("Case %d: ", ncase++);
    72         if (fla && tot == n) puts("YES");
    73         else puts("NO");
    74     }
    75     return 0;
    76 }
    二分图染色

    转载

  • 相关阅读:
    查看docker程序使用的内存脚本
    shell分割字符串并赋值给变量
    【Ceph】Ceph学习理解Ceph的三种存储接口:块设备、文件系统、对象存储
    删除软连接导致源文件一起被删除
    nginx+keepalived实现双活
    maven私有仓库的搭建
    直接访问nginx ip地址返回404错误
    Solaris基础系列之四:图解Oracle 10g安装
    数据库进阶系列之一:漫谈数据库索引
    Tips&Tricks系列四:C#面试笔试小贴士
  • 原文地址:https://www.cnblogs.com/ACMERY/p/4787577.html
Copyright © 2020-2023  润新知