CSU - 1356 Catch (判奇环)

题目传送门:CSU - 1356 Catch 

题目大意:

存在一个n个点m条边的无向图,给定一个出发点,每个时间点能够走到相邻的下个点。能够走重复的边,

问是否存在某一个时间点,他可能停留再任意的n个点之间。

分析:

首先图是联通的,不连通则无法到达一部分点,可以发现如果该图是一条链的话,到达的点分两种情况

(奇数时间到达和偶数时间到达)因此无法满足条件。当图是一个偶数环时,同样无法满足要求,可以分析

只有存在奇数环的时候才能满足再某一时刻处于任何位置。所以题目即判断该图中是否存在奇数环即可

代码:

搜索过程中,给每个点一个val值,每次+1,当找到一条边上,两个val值相差+1为奇数则存在奇数环

#include<iostream>
#include<vector>
#include<cstring>
#include<cmath>
using namespace std;
const int MAX=100000+9;
int t,n,m,s,u,v;
int vis[MAX];
vector<int>G[MAX];
bool dfs(int u,int val)
{
    vis[u]=val;
    for(int i=0;i<G[u].size();i++){
        int v=G[u][i];
        if(!vis[v])dfs(v,val+1);
        else if(abs(vis[u]-vis[v])%2==0)return true;    //存在奇环    
    }
    return false;
}
int main()
{
    int cas=1;
    scanf("%d",&t);
    while(t--)
    {
        memset(vis,0,sizeof(vis));
        for(int i=0;i<MAX;i++)
            G[i].clear();
        printf("Case %d: ",cas++);
        scanf("%d%d%d",&n,&m,&s);
        for(int i=0;i<m;i++){
            scanf("%d%d",&u,&v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
        if(dfs(s,1))printf("YES\n");
        else printf("NO\n");
    }
    return 0;
} 
View Code

染色法:就是给每个点进行标号,初始值全为-1,标为0,1 如果存在一条边连接的两个点标号相同,

那么就是存在一个奇数环

#include<iostream>
#include<vector>
#include<cstring>
#include<cmath>
using namespace std;
const int MAX=100000+9;
int t,n,m,s,u,v;
int vis[MAX];
vector<int>G[MAX];
bool dfs(int u,int val)
{
    vis[u]=val;
    for(int i=0;i<G[u].size();i++){
        int v=G[u][i];
        if(vis[v]==-1)dfs(v,!val);            //标记为0 1 
        else if(vis[v]==val)return true;    //该边两点标记相同,存在奇环    
    }
    return false;
}
int main()
{
    int cas=1;
    scanf("%d",&t);
    while(t--)
    {
        memset(vis,-1,sizeof(vis));            //初始值全为-1 
        for(int i=0;i<MAX;i++)
            G[i].clear();
        printf("Case %d: ",cas++);
        scanf("%d%d%d",&n,&m,&s);
        for(int i=0;i<m;i++){
            scanf("%d%d",&u,&v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
        if(dfs(s,0))printf("YES\n");
        else printf("NO\n");
    }
    return 0;
} 
View Code

猜你喜欢

转载自www.cnblogs.com/LjwCarrot/p/10739683.html