CSU 1356 Catch

  原题链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1356

  题目需要我们判断给定图在某一步是否会有可能出现在所有节点。首先,我们不妨假设给定图是一条单链,那么无论何时,都是“NO”的情况,因为某一时刻总是奇点或偶点(因为点是同步的,奇点相邻总是偶点,偶点相邻总是奇点)。同理,假设给定图示一个偶圈,同样得出是“NO”的情况;最终,我们得出得出只有是寄圈的情况下才满足“YES”的情况。

  所以我们的任务就是判断寄圈,这里我用的是染色法,直接对图进行深搜同时标记颜色,应该是最通用的求寄圈的方法了。

#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <queue>
#include <cassert>
using namespace std;
//#pragma comment(linker, "/STACK:102400000,102400000")
#define pii         pair<int,int>
#define clr(a)      memset((a),0,sizeof (a))
#define rep(i,a,b)  for(int i=(a);i<=(int)(b);i++)
#define per(i,a,b)  for(int i=(a);i>=(int)(b);i--)
#define inf         (0x3f3f3f3f)
#define eps         1e-6
#define N           100005
#define M           4000005
#define MODN        1000000007
#define RI(x)       scanf("%d", &x)
#define RII(x,y)    scanf("%d%d", &x, &y)
#define RIII(x,y,z) scanf("%d%d%d", &x, &y, &z)
#define debug       puts("reach here");
typedef long long LL;

int n, m, s;
int a, b;
int ne;
int head[N];
int color[N];

struct node
{
    int v;
    int next;
}E[M];

void add_edge(int u, int v)
{
    E[ne].v = v;
    E[ne].next = head[u];
    head[u] = ne++;
}

void init()
{
    memset(head, -1, sizeof head);
    memset(color, 0, sizeof color);
    ne = 0;
}

bool dfs(int u)
{
    for(int i = head[u]; i != -1; i = E[i].next)
    {
        int v = E[i].v;
        if(color[v] == 0)
        {
            color[v] = color[u] % 2 + 1;
            if(dfs(v))
                return true;
        }
        else
        {
            if(((color[u] + color[v]) % 2) == 0)
                return true;
        }
    }
    return false;
}

int main()
{
    int t;
    RI(t);
    rep(cas,1,t)
    {
        RIII(n, m, s);
        init();
        rep(i,0,m-1)
        {
            RII(a, b);
            add_edge(a, b);
            add_edge(b, a);
        }
        color[s] = 1;
        printf("Case %d: ", cas);
        if(dfs(s)) puts("YES");
        else puts("NO");
        
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/huangfeihome/p/3624160.html