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

 

posted @ 2016-08-04 20:43  西瓜不懂柠檬的酸  Views(385)  Comments(0Edit  收藏  举报
levels of contents