zoukankan      html  css  js  c++  java
  • Codeforces936B. Sleepy Game

    还好这场没打 MD什么破题

    n<=100000,m<=200000的图问从s点出发能否走奇数条边到一个没有出度的点。

    直观的想法:做一个bfs,$f(i,0/1)$表示从$s$出发到$i$能否走奇数/偶数条边,搜出来,找一个$f(t,1)=1$ && $ chudu(t)=0$的点做终点。

    如果找不到,就看能否走进一个环。

    然后开始跳坑辣!(排名不分先后)

    坑一:能否走进一个环,咋写?我先这样写的

    mdzz,直接搜好像不靠谱。。老老实实写tarjan吧

    坑二:最后构造答案,咋写?

    法一:反向图再跑一次bfs,从起点开始跑,看一条边两端的点是否一个$f(i,1)=1$一个$f(j,0)=1$,能就走。然后挂了。

    由于路上可能有一个偶环,为了不让人在里面死循环,我先判的一个点不经过超过两次。

    然后有这个图:

    你xx在玩我!

    坑三:

    法二:zz吧直接bfs的时候记个前驱,从终点开始往前跑,跑到起点结束。嗯好像没啥毛病。

    。。。。。。。。。。。。。。。

    好吧往前跑的时候记一下奇数条边还是偶数,偶数就别停了。

      1 //#include<iostream>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<cstdio>
      5 //#include<map>
      6 #include<math.h>
      7 //#include<time.h>
      8 //#include<complex>
      9 #include<algorithm>
     10 using namespace std;
     11 
     12 int n,m,s;
     13 #define maxn 200011
     14 #define maxm 200011
     15 struct Edge{int to,next;};
     16 struct Graph
     17 {
     18     Edge edge[maxm]; int first[maxn],le; bool du[maxn];
     19     Graph() {le=2;}
     20     void in(int x,int y) {Edge &e=edge[le]; e.to=y; e.next=first[x]; first[x]=le++; du[x]=1;}
     21     
     22     bool d[maxn],b[maxn],vis[maxn]; int pd[maxn],pb[maxn];
     23     int que[maxn],head,tail;
     24     void sh(int s)
     25     {
     26         que[head=(tail=1)-1]=s;
     27         d[s]=0; b[s]=1; vis[s]=1;
     28         while (head!=tail)
     29         {
     30             int now=que[head++]; if (head==maxn) head=0; vis[now]=0;
     31             for (int i=first[now];i;i=edge[i].next)
     32             {
     33                 Edge &e=edge[i];
     34                 if (d[e.to]==0 && b[now])
     35                 {
     36                     d[e.to]=1; pd[e.to]=now;
     37                     if (!vis[e.to])
     38                     {
     39                         vis[e.to]=1;
     40                         que[tail++]=e.to;
     41                         if (tail==maxn) tail=0;
     42                     }
     43                 }
     44                 if (b[e.to]==0 && d[now])
     45                 {
     46                     b[e.to]=1; pb[e.to]=now;
     47                     if (!vis[e.to])
     48                     {
     49                         vis[e.to]=1;
     50                         que[tail++]=e.to;
     51                         if (tail==maxn) tail=0;
     52                     }
     53                 }
     54             }
     55         }
     56     }
     57     
     58     int dfn[maxn],Time,low[maxn],sta[maxn],top; bool insta[maxn];
     59     bool dfs(int x)
     60     {
     61         low[x]=dfn[x]=++Time;
     62         sta[++top]=x; insta[x]=1;
     63         for (int i=first[x];i;i=edge[i].next)
     64         {
     65             Edge &e=edge[i];
     66             if (!dfn[e.to])
     67             {
     68                 if (dfs(e.to)) return 1;
     69                 low[x]=min(low[x],low[e.to]);
     70             }
     71             else if (insta[e.to]) low[x]=min(low[x],dfn[e.to]);
     72         }
     73         if (dfn[x]==low[x])
     74         {
     75             if (sta[top]!=x) return 1;
     76             top--; insta[x]=0;
     77         }
     78         return 0;
     79     }
     80     bool roll(int s) {Time=top=0; return dfs(s);}
     81 }g,fg;
     82 
     83 int ans[maxn*10],lans=0;
     84 int main()
     85 {
     86     scanf("%d%d",&n,&m);
     87     for (int i=1,x,y;i<=n;i++)
     88     {
     89         scanf("%d",&x);
     90         for (int j=1;j<=x;j++) scanf("%d",&y),g.in(i,y),fg.in(y,i);
     91     }
     92     int s,t=0;
     93     scanf("%d",&s);
     94     g.sh(s);
     95     for (int i=1;i<=n;i++) if (!g.du[i] && g.d[i]) {t=i; break;}
     96     if (t)
     97     {
     98         puts("Win");
     99         for (int x=t,sb=0;x!=s || ((lans&1)==0);sb^=1)
    100         {
    101             ans[++lans]=x;
    102             if (sb) x=g.pb[x];
    103             else x=g.pd[x];
    104         }
    105         ans[++lans]=s;
    106         for (int i=lans;i;i--) printf("%d ",ans[i]);
    107     }
    108     else
    109     {
    110         if (g.roll(s)) puts("Draw");
    111         else puts("Lose");
    112     }
    113     return 0;
    114 }
    View Code
  • 相关阅读:
    字符型数据(char)与无符号字符型数据的区别(unsigned char)
    Delphi 动态数组、静态数组、TBytes 的区别
    设置dbgrideh的footer
    Electron13之remote模块使用
    源码学习攻略
    使用git子模块实现代码复用
    关于 iframe 在隐藏后显示时,不能保持原有滚动条位置的处理
    字符串分割(String.Split)时连同分隔符一起返回
    008-Linux服务器如何查看自己的公网出口IP地址
    010-核心技术-netty-编码解码机制、protobuf、Netty入站出站机制、netty与log结合
  • 原文地址:https://www.cnblogs.com/Blue233333/p/8475439.html
Copyright © 2011-2022 走看看