SG函数-博弈论

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SG函数-博弈论相关的知识,希望对你有一定的参考价值。

b:时间限制:1s空间限制:64M题目大意:有一个图有n个点,且有m条通道连通这n个点,其中第1个点的能量永远恒定为0,初始所有点的能量均为0。第i条通道连接着x_i,y_i两个点,而且它两端点的能量之差不会超过c_i。在整个图中有k个能量源,初始的时候能量源均为休眠状态。现在Alice和Bob玩一个游戏,他们轮流进行操作,每次操作可以选择一个能量源激活,在一个能量源被激活的时候,它将会把当前节点的能量尽可能增大,且其他的点的能量会因为通道的连接同时增大。当当前点的能量达到最大值之后(由于点1的限制),操作者需要将其移动到可以使它的能量更大的相邻点,使它进入休眠状态,所有点的能量归0。如果不存在这样的相邻点,那么可以将该能量源摧毁,注意在可以移动时是不能摧毁它的。当图中没有能量源时该玩家输掉这个游戏。问Alice是否有必胜策略。输入格式:本题有多组测试数据。对于每组测试数据,第一行三个数n,m,k。接下来m行,每行三个数x_i,y_i,c_i。接下来一行k个数,表示k个能量源的位置。输出格式:对于每组数据,如果Alice必胜则输出"Alice",否则输出"Bob"(不含引号)。样例输入:4 5 21 2 32 3 21 3 43 4 12 4 11 24 5 31 2 32 3 21 3 43 4 12 4 12 3 4样例输出:AliceBob数据范围:对于10%的数据:n,k <= 8, m <= 20对于另20%的数据:k=1对于60%的数据:n,k <= 200, m <=500对于另20%的数据:k=2对于100%的数据:数据组数 <= 10, n,k <= 20000, m <= 50000, 1 <= c_i <=10000 
具体论文可查百度:SG函数、博弈论等关键词。
该游戏的必胜情况为各个子游戏Sg值的异或,
即SG(G)=SG(g1) xor SG(g2) xor……xor SG(gn)
我们定义mex({一个整数集合S})=最小的不在集合S中的正整数
则SG(gn)=mex({SG(gm)|状态gn可以转移到状态gm})

该题标程:(被卡常数,略超1s)

 1 #include<iostream>
 2 #include<cstdlib>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #include<vector>
 6 #include<queue>
 7 using namespace std;
 8 struct edge{
 9        int to,cap;
10        friend bool operator<(const edge a,const edge b){
11               return a.cap<b.cap;
12        }
13 };
14 edge p[20001];
15 vector <edge> E[20001];
16 int  dist[20001];
17 bool mex[20001],used[20001];
18 int sg[20001];
19 int n,m,k;
20 void addedge(int from,int to,int c){
21      E[from].push_back((edge){to,c});
22 }
23 void spfa(){
24      memset(dist,-1,sizeof(dist));
25      memset(used,0,sizeof(used));
26      queue <int> q;
27      q.push(1);
28      dist[1]=0;used[1]=true;
29      while(q.size()>0){
30                        int now=q.front();q.pop();
31                        for(int i=0;i<E[now].size();i++){
32                                edge tmp=E[now][i];
33                                if(dist[tmp.to]==-1||dist[tmp.to]>dist[now]+tmp.cap)
34                                {
35                                      dist[tmp.to]=dist[now]+tmp.cap;
36                                      if(!used[tmp.to]){
37                                                        q.push(tmp.to);
38                                                        used[tmp.to]=true;
39                                      }
40                                }
41                        }
42                        used[now]=false;
43      }
44 }                                                                                                                                                  
45 int main(){
46     //freopen("b.in","r",stdin);freopen("b.out","w",stdout);
47     int x,y,c;
48     while(scanf("%d%d%d",&n,&m,&k)!=EOF)
49     {
50         for(int i=1;i<=n;i++)E[i].clear();
51         for(int i=0;i<m;i++){
52                 scanf("%d%d%d",&x,&y,&c);
53                 addedge(x,y,c);
54                 addedge(y,x,c);
55         }
56         spfa();
57         for(int i=1;i<=n;i++)
58                 p[i]=((edge){i,dist[i]});
59         sort(p+1,p+n+1);
60         int t=n;  
61         while(t>0){
62                    bool f=false;
63                    memset(mex,0,sizeof(mex));
64                    for(int i=0;i<E[p[t].to].size();i++){
65                            int tmp=E[p[t].to][i].to;
66                            if(dist[tmp]>p[t].cap){mex[sg[tmp]]=true;f=true;}
67                    }
68                    for(int i=0;1;i++){
69                            if(mex[i]==false){sg[p[t].to]=i;break;}
70                    }
71                    if(f==false) sg[p[t].to]=1;
72                    t--;
73         }
74         int ans=0;                  
75         for(int i=0;i<k;i++){
76                 scanf("%d",&x);
77                 ans=ans^sg[x];
78         }
79         printf(ans?"Alice\n":"Bob\n");
80     }
81     
82     //fclose(stdin);fclose(stdout);
83     return 0;
84 }

 

以上是关于SG函数-博弈论的主要内容,如果未能解决你的问题,请参考以下文章

博弈论题目总结——SG组合游戏及变形

ACM博弈论SG函数入门:博弈树SG函数的转移与子游戏的合并

POJ 2960 S-Nim 博弈论 sg函数

博弈论初步(SG函数)

JZYZOJ1540 BZOJ4035 [ haoi2015 上午] T3 博弈论 sg函数 分块

博弈论进阶之SG函数