zoukankan      html  css  js  c++  java
  • cf1149E. Election Promises

    题目描述

    题解

    有向无环图的博弈游戏有个小技巧就是把点分组,每个点 $u$ 所在的集合 $M(u)=\text{mex}\{M(v)|(u,v)\in G\}$

    然后如果每个组的异或值为 $0$ 的话,那么就是先手必败,否则先手必胜。

    因为我们可以考虑找到异或值不为 $0$ 的最大编号的组,然后把其中一个数 $x$ 减小至这个组异或值为 $0$ ,然后对于 $x$ 的出边所指的点 $v$ ,把 $v$ 点改为使得其组异或值为 $0$ 的值。这样就是每个组异或值都为 $0$ 的情况了。因此先手必胜。

    求 $\text{mex}$ 只要 $\text{bfs}$ 一遍就好了,效率: $O(n+m)$ 。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N=2e5+5;
    int n,m,a[N],hd[N],V[N],nx[N],t,g[N],p[N],s[N],in[N];
    vector<int>e[N];
    queue<int>q;
    void add(int u,int v){
        nx[++t]=hd[u];V[hd[u]=t]=v;
    }
    int main(){
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for (int i=1,u,v;i<=m;i++)
            scanf("%d%d",&u,&v),
            add(v,u),in[u]++,
            e[u].push_back(v);
        for (int i=1;i<=n;i++)
            if (!in[i]) q.push(i);
        for (;!q.empty();){
            int u=q.front(),z;q.pop();
            for (int i=hd[u];i;i=nx[i])
                if (!(--in[V[i]])) q.push(V[i]);
            z=e[u].size();
            for (int i=0;i<z;i++) p[g[e[u][i]]]=u;
            for (int i=0;;i++) if (p[i]!=u){
                g[u]=i;s[i]^=a[u];break;
            }
        }
        for (int i=n;~i;i--){
            if (!s[i]) continue;
            puts("WIN");
            for (int j=1,z;j<=n;j++)
                if (g[j]==i && (s[i]^a[j])<a[j]){
                    a[j]=(s[i]^a[j]);
                    z=e[j].size();
                    for (int v,k=0;k<z;k++)
                        v=e[j][k],a[v]=s[g[v]]^a[v],s[g[v]]=0;
                    break;
                }
            for (int j=1;j<=n;j++)
                printf("%d%c",a[j],j<n?' ':'\n');
            return 0;
        }
        puts("LOSE");
        return 0;
    }
  • 相关阅读:
    Codeforces Round #600 (Div. 2) A. Single Push
    Codeforces Round #600 (Div. 2) B. Silly Mistake
    106. 从中序与后序遍历序列构造二叉树
    23. 合并K个升序链表
    203. 移除链表元素
    328. 奇偶链表
    86. 分隔链表
    面试题 02.05. 链表求和
    面试题 02.02. 返回倒数第 k 个节点
    剑指 Offer 18. 删除链表的节点
  • 原文地址:https://www.cnblogs.com/xjqxjq/p/15534904.html
Copyright © 2011-2022 走看看