• CSU


    题目传送门: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
    ");
            else printf("NO
    ");
        }
        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
    ");
            else printf("NO
    ");
        }
        return 0;
    } 
    View Code
  • 相关阅读:
    2008年总结
    感触
    24105
    事情总喜欢蜂拥而至
    最后的稻草
    什么叫服务
    sigh,终于submit了
    在工作和生活的狭缝中生存着
    不应该,不应该
    ren 人 认 忍 韧 仁
  • 原文地址:https://www.cnblogs.com/LjwCarrot/p/10739683.html
Copyright © 2020-2023  润新知