Catch---hdu3478(染色法判断是否含有奇环)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3478

题意:有n个路口,m条街,一小偷某一时刻从路口 s 开始逃跑,下一时刻都跑沿着街跑到另一路口,问是否存在某一时刻出,小偷可能出现在任意路口;

如果小偷能走一个环,如果这个环是偶数个节点,那么某个节点只能在偶数时刻或者奇数时刻到达;

但是如果这个环是奇数个节点,他既可以在奇数时刻到达又可以在偶数时刻到达;所以这道题就是求是否存在一个奇环;如果存在输出YES,否则NO;

由于二分图中不能含有奇环,所以我们只需用染色法判断是否是二分图即可;

详细题解

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
#include <stack>
#include <math.h>

using namespace std;

#define met(a, b) memset(a, b, sizeof(a))
#define N 100003
#define INF 0x3f3f3f3f
const int MOD = 1e9+7;

typedef long long LL;

vector<vector<int> >G;

int c[N], n, m, s;

int flag;

void dfs(int u)
{
    int len = G[u].size();
    for(int i=0; i<len; i++)
    {
        int v = G[u][i];
        if(c[v] == -1)
        {
            c[v] = c[u]^1;
            dfs(v);
        }
        else if(c[v] == c[u])
        {
            flag = 1;
            return;
        }
    }
    return ;
}

int main()
{
    int T, t = 1;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d %d %d", &n, &m, &s);
        G.clear();
        G.resize(n+5);
        for(int i=1; i<=m; i++)
        {
            int u, v;
            scanf("%d %d", &u, &v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
        met(c, -1);
        flag = 0;
        printf("Case %d: ", t++);
        dfs(s);
        if(flag)puts("YES");
        else puts("NO");
    }
    return 0;
}

dfs

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
#include <stack>
#include <math.h>

using namespace std;

#define met(a, b) memset(a, b, sizeof(a))
#define N 100003
#define INF 0x3f3f3f3f
const int MOD = 1e9+7;

typedef long long LL;

vector<vector<int> >G;

int c[N], n, m, s;

int bfs()
{
    met(c, -1);
    queue<int>Q;
    Q.push(s);
    c[s] = 0;
    while(!Q.empty())
    {
        int p = Q.front();Q.pop();
        int len = G[p].size(), q;
        for(int i=0; i<len; i++)
        {
            q = G[p][i];
            if(c[q] == -1)
            {
                c[q] = c[p]^1;
                Q.push(q);
            }
            else if(c[q] == c[p])
                return 1;///说明存在奇环,不是二分图;
        }
    }
    return 0;
}

int main()
{
    int T, t = 1;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d %d %d", &n, &m, &s);
        G.clear();
        G.resize(n+5);
        for(int i=1; i<=m; i++)
        {
            int u, v;
            scanf("%d %d", &u, &v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
        printf("Case %d: ", t++);
        if(bfs())puts("YES");
        else puts("NO");
    }
    return 0;
}

bfs

时间: 2024-10-14 11:00:35

Catch---hdu3478(染色法判断是否含有奇环)的相关文章

UVA 1364 - Knights of the Round Table (找双连通分量 + 二分图染色法判断)

都特么别说话,我先A了这道题! 卧槽啊.....! 题意来自 kuangbin: 亚瑟王要在圆桌上召开骑士会议,为了不引发骑士之间的冲突, 并且能够让会议的议题有令人满意的结果,每次开会前都必须对出席会议的骑士有如下要求: 1.  相互憎恨的两个骑士不能坐在直接相邻的2个位置: 2.  出席会议的骑士数必须是奇数,这是为了让投票表决议题时都能有结果. 注意:1.所给出的憎恨关系一定是双向的,不存在单向憎恨关系. 2.由于是圆桌会议,则每个出席的骑士身边必定刚好有2个骑士. 即每个骑士的座位两边都

poj2942 双联通分量+交叉染色法判断二分图

Knights of the Round Table Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 11805   Accepted: 3870 Description Being a knight is a very attractive career: searching for the Holy Grail, saving damsels in distress, and drinking with the oth

染色法判断二分图

染色法判断二分图 给一个无向图,判断是否是二分图. 这很简单: 1.把节点1染为1. 2.搜索各点,遍历与此点u相连的点v. 3.如果点v没颜色,把它染为与点u相反的颜色(即-u). 4.如果有颜色,则比较v与u颜色是否相同.若相同,返回0:若不同,则继续. 代码: 1 #include<cstdio> 2 #define N 420000 3 int head[N],next[N],to[N],rs[N],n,m,a,b,y,num; 4 int dfs(int x){ 5 for(int

染色法判断是否是二分图 hdu2444

用染色法判断二分图是这样进行的,随便选择一个点, 1.把它染成黑色,然后将它相邻的点染成白色,然后入队列 2.出队列,与这个点相邻的点染成相反的颜色 根据二分图的特性,相同集合内的点颜色是相同的,即 但是如果这个图不是二分图,那么就会这样 把与1相邻的点2,3染成白色,然后入队列,然后2出队列,要把与2相邻的点2,3染成黑色,但是都染过了,所以不用染色 但是3的颜色应该与2相反(如果是二分图的话),可是没有相反,所以就不是二分图 1 #include <stdio.h> 2 #include

交叉染色法判断二分图

题目链接:传送门 题目大意:给你一副无向联通图,判断是不是二分图 题目思路:交叉染色法 下面着重介绍下交叉染色法的定义与原理 首先任意取出一个顶点进行染色,和该节点相邻的点有三种情况: 1.未染色    那么继续染色此节点(染色为另一种颜色) 2.已染色但和当前节点颜色不同      跳过该点 3.已染色并且和当前节点颜色相同       返回失败(该图不是二分图) 下面在拓展两个概念: (1) 如果一个双连通分量内的某些顶点在一个奇圈中(即双连通分量含有奇圈),那么这个双连通分量的其他顶点也在

南阳理工1015 (染色法判断二分图)

题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=1015 二部图 时间限制:1000 ms  |  内存限制:65535 KB 难度:1 描述 二部图又叫二分图,我们不是求它的二分图最大匹配,也不是完美匹配,也不是多重匹配,而是证明一个图是不是二部图.证明二部图可以用着色来解决,即我们可以用两种颜色去涂一个图,使的任意相连的两个顶点颜色不相同,切任意两个结点之间最多一条边.为了简化问题,我们每次都从0节点开始涂色 输入 输入: 多组数据

【01染色法判断二分匹配+匈牙利算法求最大匹配】HDU The Accomodation of Students

http://acm.hdu.edu.cn/showproblem.php?pid=2444 [DFS染色] 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<cmath> 6 #include<algorithm> 7 8 using namespace std; 9 const int maxn=2e2

[cf557d]Vitaly and Cycle(黑白染色求奇环)

题目大意:给出一个 n 点 m 边的图,问最少加多少边使其能够存在奇环,加最少边的情况数有多少种. 解题关键:黑白染色求奇环,利用数量分析求解. 奇环:含有奇数个点的环. 二分图不存在奇环.反之亦成立. #include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<iostream> #include<cmath> using nam

二分图的判定(染色法)和二分图最大匹配(匈牙利)算法及模板

定义 二分图也称二部图,是图论里的一种特殊模型,也是一种特殊的网络流.其最大的特点在于,可以将图里的顶点分为两个集合,且集合内的点没有直接关联,如下图所示. 如果某个图为二分图,那么它至少有两个顶点,且其所有回路的长度均为偶数,任何无回路的的图均是二分图. 1.染色法判断二分图 染色法是对每一个点深搜,与这个点连接的点颜色与此点相反,如果存在环且是偶数环或则不存在环,则满足该条件,如果存在奇数环则不满足(推出矛盾) #include<iostream> #include<cstring&