• Codeforces 937 D. Sleepy Game(DFS 判断环)


    题目链接: Sleepy Game

    题意:

      Petya and Vasya 在玩移动旗子的游戏, 谁不能移动就输了。 Vasya在订移动计划的时候睡着了, 然后Petya 就想趁着Vasya睡着的时候同时定下策略, 如果可以赢得话输出Win 并输出路径, 如果步数在达到1e6的情况下,就认定为平局, 输出Draw,如果输的话就输出lost。

    题解:

      这题很容易就可以想到如果图中存在奇数长度的路径从起始点到叶子结点就是Win状态(这里还要注意绕环走的情况,比如说奇数长度的环是可以改变路径的奇偶性的),如果不存在奇数长度的路径但是存在环的话就是Draw,如果都不是就是Lost。写了以后深深地发现自己的DFS是真的挫,如何判断有向图的环@。@! DFS的时候:

    res[u][0]==1表示u这个点能从s点偶数路径到达

    res[u][1]==1表示u这个点能从s点奇数路径到达

    如果dfs到某点发现res的值已经为1就不用再继续下去了,这样就能保证dfs时每个点最多被访问2次。那么如果存在一个点x,使得res[x][1]==1且x的出度为0,那么就是Win的方案。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int MAX_N = 1e5+9;
     4 int res[MAX_N][2],point[MAX_N],num_s,st[MAX_N*4],vis[MAX_N];
     5 vector<int> vec[MAX_N];
     6 int N,M,x;
     7 void init()
     8 {
     9     num_s = 0;
    10     memset(st,0,sizeof(st));
    11     memset(vis,0,sizeof(vis));
    12     memset(res,0,sizeof(res));
    13     memset(point,0,sizeof(point));
    14     for(int i=0; i<MAX_N; i++) vec[i].clear();
    15 }
    16 bool dfs(int pos,int x)
    17 {
    18     if(res[pos][x^1] == 1) return false;
    19     res[pos][x^1] = 1;
    20     st[num_s ++] = pos;
    21     if(vec[pos].size() == 0 && res[pos][1])
    22     {
    23         return true;
    24     }
    25     for(int i=0; i<vec[pos].size(); i++)
    26     {
    27         if(dfs(vec[pos][i],x^1)) return true;
    28     }
    29     num_s --;
    30     return false;
    31 }
    32 bool cheak(int pos)
    33 {
    34     vis[pos]=1;
    35     bool f=false;
    36     for(int i=0; i<vec[pos].size(); i++)
    37     {
    38         if(vis[vec[pos][i]]==1) f=true;
    39         else if(vis[vec[pos][i]]==0) f=cheak(vec[pos][i]);
    40         if(f) return true;
    41     }
    42     vis[pos] = 2;
    43     return false;
    44 }
    45 int main()
    46 {
    47     cin>>N>>M;
    48     init();
    49     for(int i=1; i<=N; i++)
    50     {
    51         int num,temp;
    52         scanf("%d",&num);
    53         for(int j=0; j<num; j++)
    54         {
    55             scanf("%d",&temp);
    56             vec[i].push_back(temp);
    57         }
    58     }
    59     int pos;
    60     cin>>pos;
    61     if(dfs(pos,1))
    62     {
    63         cout<<"Win"<<endl;
    64         for(int i=0; i<num_s; i++)
    65         {
    66             printf("%d ",st[i]);
    67         }
    68         cout<<endl;
    69     }
    70     else if(cheak(pos))
    71         cout<<"Draw"<<endl;
    72     else
    73         cout<<"Lose"<<endl;
    74 }
  • 相关阅读:
    将各种简单算法组合,使自己更加灵活的使用它
    转载 原反补码
    迭代器是神马东西
    进程 线程
    STL中的容器是如何实现的,如何存储的
    可以实例化对象,但是不能被继承的类
    float的存储及和int的转化
    对批处理、多道操作系统的理解
    STL set、map实现为什么要以红黑树为底层实现机制?
    c 多线程
  • 原文地址:https://www.cnblogs.com/doggod/p/8496100.html
Copyright © 2020-2023  润新知