首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

UVA 12530 Game of Tiles (二分图完备婚配,博弈)

2013-03-19 
UVA 12530Game of Tiles (二分图完备匹配,博弈)转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?view

UVA 12530 Game of Tiles (二分图完备匹配,博弈)

转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove

题目:给出一个n*m的格子。有一些障碍物。两人轮流,第一个人先选定某个位置,后一个人只能在前一个人选的位置相邻的位置。不能移动者输。不能选择已经选过的位置 。http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3975  同样还是2012年lartin america的题。。。第一次接触这种博弈。大致做法是这样的:对于某一个连通块,当第一个选定位置之后,根据相邻的染色可以发现把所有的位置染成两种颜色,可以构建二分图。如果这个二分图存在完备匹配的话,也就是先手随便在哪下,后手总能找到与其匹配的位置。那么后手必胜。这样以来就是判断所有的连通块是否存在完备匹配。
#include<iostream>#include<cstdio>#include<cstring>#include<vector>#define N 1255#define pb(a) push_back(a)#define mem(a,b) memset(a,b,sizeof(a))using namespace std;struct Node{    int v,next;}e[100005];vector<int>v[N];int n,m;int tot,start[N];int flag[55][55];char str[55][55];int w,b;int way[4][2]={0,1,0,-1,1,0,-1,0};int pre[N];bool mark[N];void add(int u,int v){    e[tot].v=v;    e[tot].next=start[u];    start[u]=tot++;}bool dfs_2(int i){        int j;      for(j=start[i];j!=-1;j=e[j].next){        int k=e[j].v;              if(!mark[k]){                      mark[k]=true;                    if(pre[k]==0||dfs_2(pre[k])){                              pre[k]=i;                          return true;                  }                }      }        return false;}    int match() {        int i,count=0;    memset(pre,0,sizeof(pre));    for(i=1;i<=w;i++){          mem(mark,false);        if(dfs_2(i))  count++;        }      return count==w;}void dfs(int x,int y,int c,int u){    for(int i=0;i<4;i++){        int xx=x+way[i][0];        int yy=y+way[i][1];        if(xx<0||yy<0||xx>=n||yy>=m||str[xx][yy]=='X')            continue;        if(c==0){            if(flag[xx][yy]){                add(u,flag[xx][yy]);                continue;            }            flag[xx][yy]=b;            add(u,b);            dfs(xx,yy,1,b++);        }        else{            if(flag[xx][yy]) continue;            flag[xx][yy]=w;            dfs(xx,yy,0,w++);        }    }}bool slove(int x,int y){    w=2;b=1;    mem(start,-1);    tot=0;    flag[x][y]=1;    dfs(x,y,0,1);    w--;b--;    if(w!=b) return false;    return match();}int main(){    while(scanf("%d%d",&n,&m)!=EOF){        mem(flag,0);        for(int i=0;i<n;i++)            scanf("%s",str[i]);        bool ans=true;        for(int i=0;i<n;i++){            for(int j=0;j<m;j++){                if(str[i][j]=='X'||flag[i][j]) continue;                if(!slove(i,j)) ans=false;            }        }        printf("%d\n",ans?2:1);    }    return 0;}



热点排行