有向图游戏 SG函数【博弈论】C++

SG函数可以用来判断在一个给定的有向图游戏中,当前局面的胜负状态。

SG函数的定义如下:

设当前节点为v,那么SG(v)为当前局面的SG值。SG(v)的定义如下:

  • 如果当前节点v没有后继节点,则SG(v) = 0

  • 如果当前节点v有若干个后继节点,分别为v1,v2,...,v_n,那么SG(v)为所有后继节点的SG值的异或和。即:SG(v) = SG(v1) XOR SG(v2) XOR ... XOR SG(v_n)

根据SG函数的定义,可以得出以下结论:

  • 如果SG(v)为0,则当前局面为必败态(先手必输);

  • 如果SG(v)不为0,则当前局面为必胜态(先手必胜);

  • SG函数具有性质:SG(v) = SG(w),当且仅当v和w的后继节点的SG值相同。

需要注意的是,有向图游戏中的SG函数只适用于无环图。对于有环图,SG函数的定义需要进一步扩展。

cpp 复制代码
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
// #define int long long
#define endl "\n"
#define KUI ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
using namespace std;
const int con = 2e5 + 4;
const int mod = 998244353;
int n, m, k, f[con];
vector<int> v[con];
int sg(int u)
{
    if (f[u] != -1)
    {
        return f[u];
    }
    set<int> s;
    for (auto x : v[u])
    {
        s.insert(sg(x));
    }
    int ans = 0;
    while (1)
    {
        if (s.count(ans) == 0)
        {
            return f[u] = ans;
        }
        ans++;
    }
}
void take()
{
    cin >> n >> m >> k;
    for (int i = 1; i <= m; i++)
    {
        int a1, a2;
        v[a1].push_back(a2);
    }
    memset(f, -1, sizeof f);
    int res = 0;
    int x;
    for (int i = 1; i <= k; i++)
    {
        cin >> x;
        res ^= sg(x);
    }
    if (res > 0)
    {
        cout << "先手必胜" << endl;
    }
    else
    {
        cout << "后手必胜" << endl;
    }
}
signed main()
{
    KUI;
    int t1 = 1;
    while (t1--)
    {
        take();
    }
    return 0;
}
相关推荐
IronMurphy5 分钟前
【算法五十七】146. LRU 缓存
算法·缓存
三品吉他手会点灯12 分钟前
STM32F103 学习笔记-24-I2C-读写EEPROM(第1节)-I2C物理层介绍
笔记·stm32·学习
MartinYeung521 分钟前
[论文学习]大型语言模型中个人可识别资讯(PII)的机器遗忘技术:UnlearnPII 基准与 PERMU_tok 方法的深度分析
人工智能·学习·语言模型
Irissgwe24 分钟前
数据结构-栈和队列
数据结构·c++·c·栈和队列
fanged26 分钟前
Linux内核学习21--V4L2学习3(应用)(TODO)
学习
两片空白34 分钟前
数据容器集合set/frozenset
数据结构
凌波粒39 分钟前
LeetCode--108.将有序数组转换为二叉搜索树(二叉树)
算法·leetcode·职场和发展
liulilittle39 分钟前
KCC:在 BBR 思路上的一次探索
网络·tcp/ip·算法·bbr·通信·拥塞控制·kcc
浦信仿真大讲堂1 小时前
达索系统SIMULIA Abaqus 2026接触和约束的增强新功能介绍
人工智能·python·算法·仿真软件·达索软件
点云侠1 小时前
PCL 生成三棱锥点云
c++·算法·最小二乘法