Bzoj - 1443 [JSOI2009]游戏Game [二分图博弈]

标签: 博弈 二分图
202人阅读 评论(0) 收藏 举报
分类:

1443: [JSOI2009]游戏Game

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1245  Solved: 575
[Submit][Status][Discuss]

Description

Input

输入数据首先输入两个整数N,M,表示了迷宫的边长。 接下来N行,每行M个字符,描述了迷宫。

Output

若小AA能够赢得游戏,则输出一行"WIN",然后输出所有可以赢得游戏的起始位置,按行优先顺序输出 每行一个,否则输出一行"LOSE"(不包含引号)。

Sample Input

3 3
.##
...
#.#

Sample Output

WIN
2 3
3 2

HINT

对于100%的数据,有1≤n,m≤100。 对于30%的数据,有1≤n,m≤5。

Source

[Submit][Status][Discuss]

第一道二分图博弈
感觉比想象的要简单
首先你一步我一步就把这个图搞成了一个二分图
我们来分析一下
加入我们能够找到这个图的完美匹配,那么当AA放下棋子之后,YY无论怎么走都要经过匹配边,接着AA走的一定是非匹配边,当走完最后一条匹配边是,AA就输了,所以如果有完美匹配直接输出LOSE
反之,如果没有完美匹配,那么一定有非匹配点
AA在非匹配点放下棋子是唯一选择,因为前面分析过放在匹配点一定输
接下来YY一定会走一条非匹配边到匹配点,因为如果还有非匹配点的话当前点一定不是非匹配点
到了匹配点AA就可以走匹配边了,而且一直走到他赢为止,为什么呢?假设当前匹配点可以到达一个非匹配点,那么一定可以再次增广,这就不满足匹配算法结束条件,不存在的。
所以说我们要求出所有可能是非匹配点的点
这就有点技巧了,考虑我们的匹配点,如果他可以到非匹配点,那么它将当前匹配边转向指向那个非匹配点是对答案没有影响的,而当前匹配点就变成了非匹配点,所以它就成为了一个答案。
由此得出了算法

枚举所有的非匹配点,从这个点开始,找一条到达匹配点的非匹配边,这个匹配点有一个匹配v,现在假设我们将当前点与匹配点匹配,那么v点成了非匹配点,于是乎就再dfs v点重复同样的步骤,即可找出所有的非必定匹配点

#include <bits/stdc++.h>
#define mp make_pair
using namespace std;
 
typedef pair< int, int > pp;
int n, m, top, ord[105][105], head[10005], tot;
vector< int > pe;
pp arc[10005];
 
struct Node
{
    int y, nxt;
    Node() {    }
    Node( int y, int nxt ) : y(y), nxt(nxt) {   }
} e[100005];
 
void Adde( int x, int y )
{
    e[++top] = Node(y, head[x]), head[x] = top;
    e[++top] = Node(x, head[y]), head[y] = top;
}
 
char s[105][105];
 
bool vis[10005], ans[10005];
int mat[10005];
 
bool Find( int u )
{
    for(int i = head[u]; i; i = e[i].nxt)
    {
        int v = e[i].y;
        if(vis[v]) continue;
        vis[v] = 1;
        if(!mat[v] || Find(mat[v])) return (mat[u] = v, mat[v] = u);
    }
    return false;
}
 
void Hung()
{
    for(int i = 0; i < (int)pe.size(); ++i)
    {
        if(mat[pe[i]]) continue;
        memset(vis, 0, sizeof(vis));
        tot += Find(pe[i]);
    }
}
 
void Dfs( int u )
{
    ans[u] = 1;
    for(int i = head[u]; i; i = e[i].nxt)
    {
        int v = e[i].y;
        if(mat[v] && !ans[mat[v]]) Dfs(mat[v]);
    }
}
 
int main()
{
    cin >> n >> m;
    for(int i = 1; i <= n ; ++i)
        scanf( "%s", s[i] + 1 );
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= m; ++j)
        {
            ord[i][j] = (i - 1) * m + j;
            arc[ord[i][j]] = mp(i, j);
            if(s[i][j] == '.')
            {
                if(s[i + 1][j] == '.') Adde(ord[i][j], ord[i][j] + m);
                if(s[i][j + 1] == '.') Adde(ord[i][j], ord[i][j] + 1);
                if(s[i - 1][j] == '.') Adde(ord[i][j], ord[i][j] - m);
                if(s[i][j - 1] == '.') Adde(ord[i][j], ord[i][j] - 1);
                pe.push_back(ord[i][j]);
            }
        }
    Hung();
    if(tot * 2 == pe.size())
    {
        puts("LOSE");
        return 0;
    }
    puts("WIN");
    for(int i = 0; i < (int)pe.size(); ++i)
        if(!mat[pe[i]]) Dfs(pe[i]);
    for(int i = 0; i < (int)pe.size(); ++i)
        if(ans[pe[i]]) printf( "%d %d\n", arc[pe[i]].first, arc[pe[i]].second );
    return 0;
}





查看评论

101个Java比.NET好的理由(1~10) (译者:陈佳新)

101个Java比.NET好的理由(1~10) (译者:陈佳新)   101 Reasons Java is Better than .NET (1~10)   作者:John Lambert   译...
  • bruce
  • bruce
  • 2003-02-09 11:01:00
  • 1882

【博弈+二分图匹配】[NOI2011]兔兔与蛋蛋游戏

题目描述DescriptionInput输入的第一行包含两个正整数 n、m。 接下来 n行描述初始棋盘。其中第i 行包含 m个字符,每个字符都是大写英文字母"X"、大写英文字母"O"或点号"."之一...
  • outer_form
  • outer_form
  • 2016-07-12 22:12:08
  • 1359

【BZOJ1443】【JSOI2009】游戏Game 二分图+博弈

题解:二分图博弈经典模型模板题。 首先黑白染色。 然后我们考虑到有一种优秀的走法,     就是先求个最大匹配,然后如果先手选择了一个最大匹配中的点,那么显然后手可以依照此点的匹配再走一步,然后先...
  • Vmurder
  • Vmurder
  • 2015-01-30 20:04:42
  • 1997

二分图博弈

Abstract 本文要讨论的是一类博弈问题,基于以下条件: 1.博弈者人数为两人,双方轮流进行决策。 2.博弈状态(对应点)可分为两类(状态空间可分为两个集合),对应二分图两边(X集和...
  • longshuai0821
  • longshuai0821
  • 2012-10-21 17:34:34
  • 1111

acd - 1403 - Graph Game(博弈 + 二分图最大匹配)

题意:N与P在玩游戏,N有 n1 个点,P有 n2 个点,N的点与P的点之间有 m 条无向边。将一个石子放在其中一点,N先移动石子,沿边移动一次,石子移动前的点及与该点相连的边被删除,接着到P移动石子...
  • SCNU_Jiechao
  • SCNU_Jiechao
  • 2014-10-29 19:12:19
  • 853

hrbust 1976 Back (2013年校赛 二分图+博弈)

#include #include #include #include using namespace std; #define clr(x) memset(x,0,sizeof(x)) struct...
  • hill_555
  • hill_555
  • 2014-03-11 20:42:44
  • 471

【bzoj1443】【JSOI2009】【游戏game】【二分图博弈】

Description Input 输入数据首先输入两个整数N,M,表示了迷宫的边长。 接下来N行,每行M个字符,描述了迷宫。 Output 若小AA能够赢得游戏,则输出一行"WIN",然...
  • sunshinezff
  • sunshinezff
  • 2016-03-14 15:14:21
  • 403

[二分图博弈] BZOJ 1443 [JSOI2009]游戏Game & BZOJ 2437 [Noi2011]兔兔与蛋蛋

二分图博弈考虑这样一类博弈问题 博弈状态可分为两类 即状态空间可分为两个集合 对应二分图X集和Y集 任意合法的决策使状态从一类跳转到另一类 可以用二分图描述 不可以转移至已访问的状态 无法转移者判负。...
  • u014609452
  • u014609452
  • 2017-03-02 20:59:47
  • 220

bzoj 1443: [JSOI2009]游戏Game 二分图博弈

题意给出一个n*m的地图,有的格子不能走。先手可以选择某个格子开始,然后到后手走,再到先手走。每个格子只能走一次,不能走的那方算输。问对于哪些格子,先手有必胜策略。 n,m...
  • qq_33229466
  • qq_33229466
  • 2017-02-22 17:43:47
  • 336

BZOJ2437:兔兔与蛋蛋(二分图博弈)

传送门 题解: 将原图黑白染色,相邻且颜色不同的格子连边,原问题则变为诸如:给定二分图和起点,每次可移动一步,不能走走过的地方,谁不能移动谁就输的博弈问题。 很显然,先手必胜当且仅当起点为最大匹...
  • qq_35649707
  • qq_35649707
  • 2018-04-09 20:05:35
  • 22
    个人资料
    等级:
    访问量: 6222
    积分: 326
    排名: 24万+
    文章存档